Mam płaski plik z 339276 wierszami tekstu o wielkości 62,1 MB. Próbuję przeczytać we wszystkich liniach, analizować je w oparciu o pewne warunki, które mam, a następnie wstawić je do bazy danych.Jak mogę odczytać duży płaski plik w Golang
Początkowo próbowałam użyć pętli bufio.Scan() i bufio.Text(), aby uzyskać linię, ale kończyło mi się miejsce w buforze. Przełączyłem się na używanie bufio.ReadLine/ReadString/ReadByte (próbowałem każdego) i miałem taki sam problem z każdym. Nie miałem wystarczającej ilości miejsca w buforze.
Próbowałem używać odczytu i ustawiania rozmiaru bufora, ale jak mówi dokument, w rzeczywistości stała, która może być mniejsza, ale nigdy większa niż 64 * 1024 bajty. Następnie spróbowałem użyć File.ReadAt, gdzie ustawiłem początkowy postilion i przeniosłem go, ponieważ przyniosłem każdą sekcję bezskutecznie. Mam spojrzał na następujących przykładów i wyjaśnień (lista nie jest wyczerpująca):
Read text file into string array (and write) How to Read last lines from a big file with Go every 10 secs reading file line by line in go
Jak czytać całego pliku (albo linia po linii lub całego rzeczy na raz) do plasterek, więc mogę iść do rzeczy?
Oto kod, który próbowałem:
file, err := os.Open(feedFolder + value)
handleError(err)
defer file.Close()
// fileInfo, _ := file.Stat()
var linesInFile []string
r := bufio.NewReader(file)
for {
path, err := r.ReadLine("\n") // 0x0A separator = newline
linesInFile = append(linesInFile, path)
if err == io.EOF {
fmt.Printf("End Of File: %s", err)
break
} else if err != nil {
handleError(err) // if you return error
}
}
fmt.Println("Last Line: ", linesInFile[len(linesInFile)-1])
Oto coś innego Próbowałem:
var fileSize int64 = fileInfo.Size()
fmt.Printf("File Size: %d\t", fileSize)
var bufferSize int64 = 1024 * 60
bytes := make([]byte, bufferSize)
var fullFile []byte
var start int64 = 0
var interationCounter int64 = 1
var currentErr error = nil
for currentErr != io.EOF {
_, currentErr = file.ReadAt(bytes, st)
fullFile = append(fullFile, bytes...)
start = (bufferSize * interationCounter) + 1
interationCounter++
}
fmt.Printf("Err: %s\n", currentErr)
fmt.Printf("fullFile Size: %s\n", len(fullFile))
fmt.Printf("Start: %d", start)
var currentLine []string
for _, value := range fullFile {
if string(value) != "\n" {
currentLine = append(currentLine, string(value))
} else {
singleLine := strings.Join(currentLine, "")
linesInFile = append(linesInFile, singleLine)
currentLine = nil
}
}
Jestem na straty. Albo nie rozumiem dokładnie, jak działa bufor, albo nie rozumiem czegoś innego. Dziękuje za przeczytanie.
Nie czytać to wszystko na raz . Gotuj na parze. Użyj 'bufio.Scanner' (ponieważ wydajesz się wskazywać na linię), przetwórz linię, wstaw do bazy, * potem zapomnij o tej linii *. –
Dziękuję za odpowiedź. Jak mogę zapomnieć o tej linii? W moich próbach użycia bufio.Scanner, gdy w moim pliku trafiam wiersz 63700 (z grubsza), przestaję czytać w nowych liniach. Rozumiem, że to dlatego, że uderzyłem w skaner MaxScanTokenSize (http://golang.org/pkg/bufio/#pkg-constants).Chciałbym przeczytać wiersz, przeanalizować go i wyrzucić, ale nie wiem jak to zrobić, aby skaner przesuwał się przez cały plik. – rvrtex
@DaveC Hm ... Bufory na parze. – fuz