Czy jest możliwe utworzenie obiektu File z InputStream


122

Czy istnieje sposób na utworzenie java.io.Fileobiektu z pliku java.io.InputStream?

Moim wymaganiem jest odczytanie pliku z pliku RAR. Nie próbuję pisać tymczasowego pliku, mam plik w archiwum RAR, który próbuję odczytać.


1
moim wymaganiem jest odczytanie pliku z pliku RAR. Załóżmy, że nie próbuję pisać tymczasowego pliku z RAR, wewnątrz RAR mam plik, po prostu muszę go przeczytać.
androidgalaxyman

Nie rozumiem pytania. Proszę o wyjaśnienie. Jeśli chcesz oryginalnego pliku z InputStream, nie było takiego: czytasz plik RAR, a nie plik. Jeśli chcesz czegoś innego, co?
Markiz Lorne,

Odpowiedzi:


88

Musisz utworzyć nowy plik i skopiować zawartość InputStreamdo tego pliku:

File file = //...
try(OutputStream outputStream = new FileOutputStream(file)){
    IOUtils.copy(inputStream, outputStream);
} catch (FileNotFoundException e) {
    // handle exception here
} catch (IOException e) {
    // handle exception here
}

Używam wygodnego, IOUtils.copy()aby uniknąć ręcznego kopiowania strumieni. Posiada również wbudowane buforowanie.


3
Nie można rozwiązać IOUtils w Android Studio, a odsyłacz, do którego się
odwołałeś,

3
org.apache.directory.studio:org.apache.commons.io musiało zostać dodane jako zależność. Mój błąd. :)
Shahraiz T.

7
Zamknij poprawnie OutputStream, spróbuj z zasobami lub IOUtils.closeQuietly. Wiem, że to tylko przykład, ale początkujący będą go kopiować dosłownie.
Rafael Membrives

59

W jednej linii:

FileUtils.copyInputStreamToFile(inputStream, file);

(org.apache.commons.io)


29

Najpierw utwórz plik tymczasowy.

File tempFile = File.createTempFile(prefix, suffix);
tempFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(in, out);
return tempFile;

Proszę podać nazwę pakietu IOUtils
Ridhuvarshan

org.apache.commons.io
Shehan Simen

Istnieje również w org.apache.axis2.util z trzecim parametrem dla funkcji kopiowania. Funkcjonalność też tam działa. Jakieś porównania dotyczące tego, czego użyć?
Ridhuvarshan

26

Od wersji Java 7 możesz to zrobić w jednym wierszu, nawet bez korzystania z zewnętrznych bibliotek:

Files.copy(inputStream, outputPath, StandardCopyOption.REPLACE_EXISTING);

Zobacz dokumentację API .


2
Jeśli używasz tego z systemem Android, wymagany jest min SDK 26.
Neph

3

Jeśli nie chcesz korzystać z innych bibliotek, tutaj jest prosta funkcja konwertować InputStreamdo OutputStream.

public static void copyStream(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while ((read = in.read(buffer)) != -1) {
        out.write(buffer, 0, read);
    }
}

Teraz możesz łatwo zapisać Inputstreamdo pliku za pomocą FileOutputStream-

FileOutputStream out = new FileOutputStream(outFile);
copyStream (inputStream, out);
out.close();

1

Proste rozwiązanie Java 11 z blokiem zasobów

public static void copyInputStreamToFile(InputStream input, File destination) {  

    try (OutputStream output = new FileOutputStream(destination)) {
        input.transferTo(output);
    } catch (IOException ioException) {
        ioException.printStackTrace();
    }

}

java.io.InputStream # transferTo jest dostępny od wersji Java 9.


0

Jeśli używasz języka Java w wersji 7 lub nowszej, możesz użyć try-with-resources, aby prawidłowo zamknąć plik FileOutputStream. Poniższy kod używa IOUtils.copy()z commons-io .

public void copyToFile(InputStream inputStream, File file) throws IOException {
    try(OutputStream outputStream = new FileOutputStream(file)) {
        IOUtils.copy(inputStream, outputStream);
    }
}  

Nie musisz zamykać OutputStream? Jak w odpowiedzi Tomasza N.
trinity420

3
@ trinity420 Zasoby określone w tryczęści inicjalizacyjnej są automatycznie zamykane po trywyjściu z bloku.
h3xStream
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.