Wie lese ich in einem großen, flachen Datei in Golang
Habe ich mir eine flache Datei, 339276 Textzeile für eine Größe von 62.1 MB. Ich bin versucht zu Lesen, in all den Zeilen, analysieren Sie, basierend auf bestimmten Bedingungen, die ich haben und dann legen Sie Sie in eine Datenbank.
Habe ich ursprünglich versucht, auf eine bufio.Scan () - Schleife und bufio.Text() der Linie ist, aber ich lief aus dem Pufferspeicher. Ich wechselte mit bufio.ReadLine/ReadString/ReadByte (ich habe versucht) und hatte das gleiche problem mit jedem. Ich hatte nicht genügend Pufferspeicher.
Versuchte ich mit Lesen und die Einstellung der Puffer-Größe, aber wie das Dokument sagt, dass es eigentlich ein const, die gemacht werden können, kleiner, aber nie größer, dass 64*1024 Byte. Ich habe dann versucht die Datei.ReadAt, wo ich die ab postilion und zog Sie an, als ich gebracht in jedem Abschnitt, ohne Erfolg. Ich habe mir die folgenden Beispiele und Erklärungen (nicht erschöpfende Liste):
Lesen Sie text-Datei in string-array (und schreiben)
Wie zu Lesen die letzten Zeilen aus einer großen Datei mit dem Wechseln alle 10 Sek.
beim Lesen der Datei Zeile für Zeile in gehen
Wie lese ich in einer gesamten Datei (entweder Zeile für Zeile oder die ganze Sache auf einmal) in eine Scheibe, so kann ich dann gehen Dinge tun, auf die Linien?
Hier ist ein code, dass ich versucht habe:
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])
Hier ist etwas, was ich sonst noch versuchte:
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
}
}
Ich bin ratlos. Entweder ich verstehe nicht genau, wie der Puffer funktioniert oder ich verstehe nicht was anderes. Vielen Dank für das Lesen.
- Lesen Sie nicht alles auf einmal. Dampf es. Verwenden
bufio.Scanner
(da Sie scheinen zeigen wollen, ist es s-line-basiert), die Prozess-Linie, legen Sie in deine db, dann vergessen Sie, dass die Linie. - Danke für die Antwort. Wie kann ich vergessen, die Zeile? In meinem versuche, die bufio.Scanner, wenn ich getroffen Zeile 63700 (in etwa) in meine Datei, die ich mit dem Lesen aufhören, in neue Linien. Mein Verständnis ist, dass es ist, weil ich auf den MaxScanTokenSize (golang.org/pkg/bufio/#pkg-constants) des Scanners. Ich würde gerne Lesen Sie die Zeile, analysiert es, und werfen es Weg, aber ich weiß nicht, wie zu tun, werfen Sie es Weg-Teil, damit der scanner hält sich durch die ganze Datei.
- Hm... Gedämpft Puffer.
- Sie vergessen eine Linie nicht durch das speichern einer Referenz auf den entsprechenden string nicht mehr. Zum Beispiel, wenn
line
ist die einzige variable, die die Zeile zu vergessen, weisen Sie etwas anderes zuline
zu vergessen, die original-content.
Du musst angemeldet sein, um einen Kommentar abzugeben.
bufio.Scan()
undbufio.Text()
in einer Schleife perfekt funktioniert für mich auf eine der Dateien mit der viel größeren Größe, so nehme ich an, Sie haben Linien überschritten Puffer-Kapazität. Dannpath, err :=r.ReadLine("\n") //0x0A separator = newline
? Sieht aus wiefunc (b *bufio.Reader) ReadLine() (line []byte, isPrefix bool, err error)
hat RückgabewertisPrefix
speziell für Ihren Anwendungsfallhttp://golang.org/pkg/bufio/#Reader.ReadLine
.Scan()
und.Text()
ich es lief wieder und hatte das gleiche problem. Dann ging ich und schaute auf die Datei, die ich war eigentlich läuft mein Programm vor und fand die Datei war das problem. Das Programm tut genau das, was es tun sollte und ich hatte schlechte Dateien auf meinem server-Seite. Lektion gelernt, manchmal ist es nicht schlecht, die Programmierung aber auch bad-Eingang. Vielen Dank für Ihre Hilfe, mit ihm machte ich mein Programm ausführen viel mehr effizient.Nicht klar ist, dass es ist notwendig, zu Lesen in allen Linien vor der Analyse Ihnen und dem einfügen in eine Datenbank. Versuchen Sie zu vermeiden, dass.
Müssen Sie eine kleine Datei: "eine flache Datei, 339276 Textzeile für eine Größe von 62.1 MB". Zum Beispiel,
Es scheint mir diese Variante von
readLines
ist kürzer und schneller als die empfohlene peterSO