2016-02-20 12 views
9

Mam duży strumień tekstu wracającego z serwisu WWW REST i chciałbym zapisać go bezpośrednio do pliku. Jaki jest najprostszy sposób na zrobienie tego?Napisz duży strumień danych do pliku w Kotlin

Napisałem następujące rozszerzenie funkcji, które DZIAŁA. Ale nie mogę oprzeć się wrażeniu, że istnieje czystszy sposób robienia tego.

Uwaga: Miałem nadzieję, że do korzystania spróbować z zasobów auto zamknąć strumienia i złożyć

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

Odpowiedz

21

można uprościć funkcję używając copyTo function:

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

Zewnętrzne "użycie" wydaje się błędem. Zamykasz/pozbywasz się w innym zakresie niż ten, w którym 'inputStream' został otwarty. –

5

Proponuję zrób tak:

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

, a następnie użyć jak:

InputStream.toFile("/some_path_to_file") 
+0

Powinieneś zawsze zamykać ten sam zakres, w którym się otworzyłeś. Jest to prawdopodobnie powód, dla którego 'copyTo' nie zamyka automatycznie zasobów dla ciebie. –

-2

Państwo musi zrobić, jak to

@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

Rozmiar bufora może być nieco za mały. Zazwyczaj używane jest między 8192 a 32768 bajtów. Na przykład, własna metoda InputStream # copyTo firmy Kotlin używa domyślnie 8192 B, a wersja Go używa 32768 (nie można jej zmienić). Źródło: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-input-stream/copy-to.html Źródło: https://golang.org/src/io/ io.go? s = 11569: 11629 # L389 – user7610

1

Moja propozycja to:

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

bez zamykania bieżącego strumienia

InputStream.toFile("/path/filename") 

także , nie zapomnij poradzić sobie z ceptions, na przykład jeśli odmówiono prawa zapisu :)