2016-02-20 3 views
9

Ho un grande flusso di testo che torna dal servizio web REST e vorrei scriverlo direttamente sul file. Qual è il modo più semplice per farlo?Scrive un grande Inputstream al file in Kotlin

Ho scritto la seguente estensione di funzione che FUNZIONA. Ma non posso fare a meno di pensare che c'è un modo più pulito per farlo.

Nota: speravo di usare cercare le risorse per auto chiudere il flusso e file

fun File.copyInputStreamToFile(inputStream: InputStream) { 
    val buffer = ByteArray(1024) 

    inputStream.use { input -> 
     this.outputStream().use { fileOut -> 

      while (true) { 
       val length = input.read(buffer) 
       if (length <= 0) 
        break 
       fileOut.write(buffer, 0, length) 
      } 
      fileOut.flush() 
     } 
    } 
} 

risposta

21

È possibile semplificare la vostra funzione utilizzando il copyTo function:

fun File.copyInputStreamToFile(inputStream: InputStream) { 
    inputStream.use { input -> 
     this.outputStream().use { fileOut -> 
      input.copyTo(fileOut) 
     } 
    } 
} 
+2

L'uso esterno sembra un errore. Stai chiudendo/eliminando un ambito diverso da quello in cui è stato aperto 'inputStream'. –

5

consiglio di fare così:

fun InputStream.toFile(path: String) { 
    use { input -> 
     File(path).outputStream().use { input.copyTo(it) } 
    } 
} 

e quindi di utilizzare come:

InputStream.toFile("/some_path_to_file") 
+0

Si dovrebbe sempre chiudere nello stesso ambito in cui è stato aperto. Probabilmente il motivo "copia" non chiude automaticamente le risorse per te. –

-2

bisogno di voi per fare come questo

@Throws 
fun copyDataBase() { 

     var myInput = context.getAssets().open(DB_NAME) 
     var outFileName = DB_PATH + DB_NAME 
     var fileOut: OutputStream = FileOutputStream(outFileName) 
     val buffer: ByteArray = ByteArray(1024) 
     var length: Int? = 0 

     while (true) { 
      length = myInput.read(buffer) 
      if (length <= 0) 
       break 
      fileOut.write(buffer, 0, length) 
     } 

     fileOut.flush() 
     fileOut.close() 
     myInput.close() 

     throw IOException() 
} 
+0

La dimensione del buffer potrebbe essere un po 'troppo piccola. Di solito viene utilizzato qualcosa tra 8192 e 32768 byte. Ad esempio, InputStream # copyTo di Kotlin usa 8192 B come valore predefinito predefinito e la copia di Go utilizza 32768 (non può essere modificata). Fonte: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-input-stream/copy-to.html Fonte: https://golang.org/src/io/ ? io.go s = 11569: 11629 # L389 – user7610

1

mia proposta è:

fun InputStream.toFile(path: String) { 
    File(path).outputStream().use { this.copyTo(it) } 
} 

senza chiudere flusso di corrente

InputStream.toFile("/path/filename") 

anche , non dimenticare di gestire ex in particolare, ad esempio se il permesso di scrittura viene negato :)