É possível criar um objeto File a partir de InputStream

121

Existe alguma maneira de criar um java.io.Fileobjeto a partir de um java.io.InputStream?

Minha exigência é ler o Arquivo de um RAR. Não estou tentando escrever um arquivo temporário, tenho um arquivo dentro do arquivo RAR que estou tentando ler.

androidgalaxyman
fonte
1
meu requisito é ler o arquivo de um RAR. Suponha que não estou tentando escrever o arquivo temporário do RAR, dentro do RAR estou tendo um arquivo, só preciso ler.
androidgalaxyman
Eu não entendo a pergunta. Por favor, esclareça. Se você quiser o arquivo original do InputStream, não há um: você está lendo um arquivo RAR, não um arquivo. Se você quiser outra coisa, o quê?
Marquês de Lorne
Possível duplicata de Como converter InputStream para arquivo virtual
Paulo Oliveira

Respostas:

87

Você precisa criar um novo arquivo e copiar o conteúdo InputStreamdesse arquivo:

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

Estou usando conveniente IOUtils.copy()para evitar a cópia manual de fluxos. Também possui buffer embutido.

Tomasz Nurkiewicz
fonte
3
Não foi possível resolver IOUtils no Android Studio e o link que você referiu é um 404.
Shahraiz T.
3
org.apache.directory.studio:org.apache.commons.io precisava ser adicionado como uma dependência. Foi mal. :)
Shahraiz T.
7
Feche corretamente o OutputStream, use um try with resources ou IOUtils.closeQuietly. Eu sei que é apenas um exemplo, mas os iniciantes irão copiá-lo literalmente.
Rafael Membrives
59

Em uma linha:

FileUtils.copyInputStreamToFile(inputStream, file);

(org.apache.commons.io)

Victor Petit
fonte
29

Crie um arquivo temporário primeiro.

File tempFile = File.createTempFile(prefix, suffix);
tempFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copy(in, out);
return tempFile;
Shehan Simen
fonte
Inclua o nome do pacote de IOUtils
Ridhuvarshan
org.apache.commons.io
Shehan Simen
Ele também existe em org.apache.axis2.util com um terceiro parâmetro para a função de cópia. A funcionalidade também funciona lá. Alguma comparação sobre o que usar?
Ridhuvarshan
26

Desde o Java 7, você pode fazer isso em uma linha, mesmo sem usar nenhuma biblioteca externa:

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

Veja os documentos da API .

rim
fonte
2
Se você usar isso com o Android, um SDK mínimo de 26 é necessário.
Neph
3

Se você não quiser usar outra biblioteca, aqui é uma função simples para converter InputStreampara 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);
    }
}

Agora você pode facilmente escrever um Inputstreamarquivo usando FileOutputStream-

FileOutputStream out = new FileOutputStream(outFile);
copyStream (inputStream, out);
out.close();
Nabin Bhandari
fonte
1

Solução Java 11 fácil com bloco try with resources

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 está disponível desde Java 9.

MariuszS
fonte
0

Se estiver usando o Java versão 7 ou superior, você pode usar try-with-resources para fechar o FileOutputStream. O código a seguir usa IOUtils.copy()de commons-io .

public void copyToFile(InputStream inputStream, File file) throws IOException {
    try(OutputStream outputStream = new FileOutputStream(file)) {
        IOUtils.copy(inputStream, outputStream);
    }
}  
h3xStream
fonte
Você não precisa fechar o OutputStream? Como na resposta de Tomasz N.
trinity420
3
@ trinity420 Os recursos especificados na tryparte de inicialização são fechados automaticamente quando o trybloco é encerrado.
h3xStream