2017-05-04 3 views
2

Ich habe eine PPM-Datei lesen mit ihren Daten verschlüsselt (Metadaten nicht verschlüsselt ist), Go verwenden und das Dateiformat mir gegeben enthält:golang: Lesen Zeichenfolge, ganze Zahlen und Bytes aus der Datei

  • Die "P3" magische Zahl (lesen als String)

  • Bildbreite (gelesen als integer)

  • Bildhöhe (gelesen als integer)

  • maximaler Farbwert (als Ganzzahl gelesen)

Dann, ich brauche der Rest der Datei zu lesen, wird die verschlüsselten Bits, die ich als eine einzige Byte-Array/Scheibe zu lesen.

z.B .:

P6 
480 360 
255 
�š��GHFHFI�GHFHFG~EG~EG~E 
... 
HFD{BR�Rz�y|�vxyyhlf%8&NFzx 

Was ist ein guter Weg String und Integer (die 4 ursprünglichen Metadatenwerte) und den Rest (verschlüsselten Teil) als Bytes aus der Datei zu lesen? Es kann am effizientesten sein, aber am saubersten (weniger Linien) ist bevorzugt.

+0

Sind die ganzen Zahlen in einem String-Darstellung, oder sind sie binär? Welche Größe haben sie oder wie sind sie abgegrenzt? Wenn sie binär sind, sind der große Endian und der kleine Endian? – JimB

+0

Ich denke, die Leute von spakin/netpbm haben eine ziemlich gute Möglichkeit, den Metadatenteil für netpbm-Dateien mit bufio zu extrahieren (siehe [github-repo] (https://github.com/spakin/netpbm/blob/master/netpbm) .go)) – skymon

+0

@ JimB das Beispiel, das ich gab, wird aus einer echten Datei extrahiert. Die Metadaten lauten wie im Beispiel "P6 \ n480 360 \ n255 \ n" und der Rest (Daten) besteht nur aus Bytes. Es ist alles in utf-8 codiert. –

Antwort

1

können Sie bufio.Reader verwenden, um die ersten drei Zeilen mit den ReadLine oder ReadString Verfahren und das Lesen des Restes der Datei mit der Read Methode zu lesen.

Nachdem Sie die ersten drei Zeilen gelesen haben, können Sie das Paket strings verwenden, um die zweite Zeile aufzuteilen, und dann das strconv-Paket, um die Strings mit Zahlen als Ganzzahlen zu analysieren.

Zum Beispiel:

r := bufio.NewReader(file) 
line1, err := r.ReadString('\n') 
if err != nil { 
    panic(err) 
} 
// repeat to read line 2 and 3 

size := strings.Split(line2, " ") 
width, err := strconv.Atoi(size[0]) 
if err != nil { 
    panic(err) 
} 
height, err := strconv.Atoi(size[1]) 
if err != nil { 
    panic(err) 
} 
// repeat with line 3 

aktualisieren:

Wie Adrian in den Kommentaren erwähnen Sie bufio.Scanner zusammen mit den bufio.ScanWordSplitFunc verwenden können, für die Metadaten zu scannen.

s := bufio.NewScanner(r) 
s.Split(bufio.ScanWords) 

var count int 
for s.Scan() && count < 4 { 
    switch count { 
    case 0: 
     magic = s.Text() 
    case 1: 
     if width, err = strconv.Atoi(s.Text()); err != nil { 
      return 
     } 
    case 2: 
     if height, err = strconv.Atoi(s.Text()); err != nil { 
      return 
     } 
    case 3: 
     if color, err = strconv.Atoi(s.Text()); err != nil { 
      return 
     } 
    } 
    count++ 
} 

https://play.golang.org/p/-rOJb_WlFf

+0

Ich habe diesen Ansatz schon einmal versucht, aber das Problem ist: Im PPM-Dateiformat können beliebige Leerzeichen zwischen den Metadaten selbst und zwischen Metadaten und Bilddaten verwendet werden. Alle Metadaten können in einer einzigen Zeile geschrieben werden ("P3 480 360 255") oder eine beliebige Kombination von Leerzeichen, nicht unbedingt Newline, und ich möchte alle Fälle abdecken. –

+0

Ein Scanner würde die Flexibilität bieten, die Sie brauchen, wenn die Begrenzer nicht konsistent sind: https://golang.org/pkg/bufio/#Scanner – Adrian

+0

@GabrielCalixto Ich habe ein Beispiel hinzugefügt, das 'bufio.Scanner' verwendet, wie @ Adrian. – mkopriva

Verwandte Themen