是否可以从 InputStream 创建一个 File 对象

Posted

技术标签:

【中文标题】是否可以从 InputStream 创建一个 File 对象【英文标题】:Is it possible to create a File object from InputStream 【发布时间】:2012-07-15 03:07:20 【问题描述】:

有没有办法从java.io.InputStream 创建一个java.io.File 对象?

我的要求是从 RAR 读取文件。我不是想写一个临时文件,我在 RAR 存档中有一个文件,我想读取它。

【问题讨论】:

我的要求是从 RAR 读取文件。假设我没有尝试从 RAR 中写入临时文件,在 RAR 中我有一个文件,只是我需要阅读。 我不明白这个问题。请说清楚。如果您想要 InputStream 中的原始文件,则没有:您正在读取 RAR 文件,而不是文件。如果你想要别的东西,什么? How to convert InputStream to virtual File的可能重复 【参考方案1】:

您需要创建新文件并将 InputStream 中的内容复制到该文件:

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

我使用方便的IOUtils.copy() 来避免手动复制流。它还具有内置缓冲功能。

【讨论】:

无法解析 android Studio 中的 IOUtils,您引用的链接是 404。 org.apache.directory.studio:org.apache.commons.io 需要添加为依赖项。我的错。 :) 请正确关闭OutputStream,使用资源尝试或IOUtils.closeQuietly。我知道这只是一个例子,但初学者会照字面地复制它。 谁能解释 File file = //... ?如何先初始化文件?【参考方案2】:

先创建一个临时文件。

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

【讨论】:

请包含 IOUtils 的包名 org.apache.commons.io 它也存在于org.apache.axis2.util中,带有用于复制功能的第三个参数。该功能也在那里工作。关于使用什么的任何比较?【参考方案3】:

一行:

FileUtils.copyInputStreamToFile(inputStream, file);

(org.apache.commons.io)

【讨论】:

【参考方案4】:

如果您不想使用其他库,这里有一个简单的函数,可以将数据从InputStream 复制到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);
    

现在,您可以使用FileOutputStream 轻松地将Inputstream 写入文件-

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

【讨论】:

【参考方案5】:

如果您使用的是Java 7 或更高版本,您可以使用try-with-resources 正确关闭FileOutputStream。以下代码使用来自commons-io 的IOUtils.copy()

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

【讨论】:

不需要关闭OutputStream吗?就像 Tomasz N 的回答一样。 @trinity420 在try 初始化部分中指定的资源会在try 块退出时自动关闭。 这个适用于安卓吗? @gumuruh 是的。 ***.com/a/24290875/89769【参考方案6】:

从 Java 7 开始,即使不使用任何外部库,您也可以在一行中完成:

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

请参阅API docs。

【讨论】:

如果你在 Android 上使用它,需要 26 的最小 SDK。【参考方案7】:

使用 try with resources 块的简单 Java 9 解决方案

public static void copyInputStreamToFile(InputStream input, File file)   

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


java.io.InputStream#transferTo 从 Java 9 开始可用。

【讨论】:

它的哪一部分使它需要 Java 11? @MauriceNino 对不起,感谢您的评论“try-with-resources – 在 Java 7 中引入”

以上是关于是否可以从 InputStream 创建一个 File 对象的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将 Process stdout InputStream 读入 NIO ByteBuffer?

是否可以从非通用应用程序使用 Wi-Fi Direct?

如何从 InputStream 创建图像,调整大小并保存?

从 OutputStream 创建 InputStream 的最有效方法

从 OutputStream 创建 InputStream 的最有效方法

如何从字符串创建 InputStream? [复制]