2013-07-02 16 views
10

In Scala, come si può decomprimere il testo contenuto in file.gz in modo che possa essere elaborato? Sarei felice di avere il contenuto del file memorizzato in una variabile o di salvarlo come file locale in modo che possa essere letto dal programma dopo.decomprimi e leggi il file gzip in scala

In particolare, sto utilizzando Scalding per elaborare dati di registro compressi, ma Scalding non definisce un modo per leggerli in FileSource.scala.

+2

È possibile estrarre il contenuto da gzip utilizzando Java 'java.util.zip. GZipInputStream' e quindi funziona con il suo contenuto – 4lex1v

+1

con la libreria dei file migliori, è 'myFile.newInputStream.gzipped.lines', in base a https://github.com/pathikrit/better-files/blob/master/README.md –

risposta

17

Ecco la mia versione:

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))) 
    } 
} 

Poi fare:

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

Volevo solo dire che ho usato questa soluzione, ma BufferedReaderIterator in questa soluzione ha generato righe nulle, a causa della natura del metodo reader.ready. Ecco una corretta [implementazione di un iteratore su BufferedReader] (http://viewfromthefringe.blogspot.de/2007/10/making-bufferedreader-iterable.html) che ho trovato –

+1

Per curiosità, quale aspetto di il file ha causato le linee null? – dhg

+1

È discusso in questo [post] (http://stackoverflow.com/questions/5244839/does-bufferedreader-ready-method-ensure-that-readline-method-does-not-return): "... The risultato di calling ready() non ti dice assolutamente nulla sul contenuto che riceverai da una chiamata a read(), e quindi non può essere usato per elidere un assegno null. " Sto usando l'iteratore per leggere i file di testo .gz dai bucket S3 e alcune righe dall'iteratore hanno restituito oggetti nulli. Poi ho cambiato l'implementazione dell'iteratore che ho allegato e ho smesso di sperimentare questo comportamento. –