2013-07-02 12 views
10

W Scala, w jaki sposób można rozpakować tekst zawarty w file.gz, aby można było go przetworzyć? Byłbym zadowolony z posiadania zawartości pliku przechowywanego w zmiennej lub zapisywania go jako pliku lokalnego, aby mógł być odczytywany przez program po.dekompresja i odczyt pliku gzip w scala

W szczególności używam Skalowania do przetwarzania skompresowanych danych dziennika, ale funkcja Skalowanie nie definiuje sposobu ich odczytania w FileSource.scala.

+2

Można wyodrębnić zawartość z gzip używając Java 'java.util.zip. GZipInputStream', a następnie pracuj z jego zawartością – 4lex1v

+1

z biblioteką lepszych plików, to 'myFile.newInputStream.gzipped.lines', zgodnie z https://github.com/pathikrit/better-files/blob/master/README.md –

Odpowiedz

17

Oto moja wersja:

import java.io.BufferedReader 
import java.io.InputStreamReader 
import java.util.zip.GZIPInputStream 
import java.io.FileInputStream 

class BufferedReaderIterator(reader: BufferedReader) extends Iterator[String] { 
    override def hasNext() = reader.ready 
    override def next() = reader.readLine() 
} 

object GzFileIterator { 
    def apply(file: java.io.File, encoding: String) = { 
    new BufferedReaderIterator(
     new BufferedReader(
     new InputStreamReader(
      new GZIPInputStream(
      new FileInputStream(file)), encoding))) 
    } 
} 

Następnie wykonaj:

val iterator = GzFileIterator(new java.io.File("test.txt.gz"), "UTF-8") 
iterator.foreach(println) 
+1

Chciałem tylko powiedzieć, że użyłem tego rozwiązania, ale BufferedReaderIterator w tym rozwiązaniu wygenerował zerowe linie, ze względu na charakter metody read.ready. Tutaj jest poprawne [wykonanie iteratora nad BufferedReader] (http://viewfromthefringe.blogspot.de/2007/10/making-bufferedreader-iterable.html), które znalazłem –

+1

Z ciekawości, jaki aspekt plik spowodował linie zerowe? – dhg

+1

Jest to omówione w [post] (http://stackoverflow.com/questions/5244839/does-bufferedreader-ready-method-ensure-that-readline-method-does-not-return): "... Wynik wywołania ready() nie mówi absolutnie nic o zawartości, którą otrzymasz z wywołania read(), więc nie można jej użyć do wymuszenia zerowej kontroli. " Używam iteratora do odczytywania plików tekstowych .gz z wiader S3, a niektóre wiersze z iteratora dają puste obiekty. Następnie zmieniłem na implementację iteratora, który załączałem i przestałem doświadczać tego zachowania. –