如何从ByteArrayOutputStream创建java.io.File?

如何从ByteArrayOutputStream创建java.io.File?,java,file-io,Java,File Io,我正在从FTP读取一堆文件。然后我需要解压这些文件并将它们写入文件共享 我不想先写文件,然后把它们读回并解压缩。我想一次完成这一切。可能吗 这是我的密码 FTPClient fileclient = new FTPClient(); .. ByteArrayOutputStream out = new ByteArrayOutputStream(); fileclient.retrieveFile(filename, out); ??????? //How do I get my out-s

我正在从FTP读取一堆文件。然后我需要解压这些文件并将它们写入文件共享

我不想先写文件,然后把它们读回并解压缩。我想一次完成这一切。可能吗

这是我的密码

FTPClient fileclient = new FTPClient();
..

ByteArrayOutputStream out = new ByteArrayOutputStream();
fileclient.retrieveFile(filename, out);

??????? //How do I get my out-stream into a File-object? 

File file = new File(?);

ZipFile zipFile = new ZipFile(file,ZipFile.OPEN_READ);

有什么想法吗?

好吧,您可以创建一个
文件输出流
,然后从中写入数据:

FileOutputStream fos = new FileOutputStream(filename);
try {
  out.writeTo(fos);
} finally {
  fos.close();
}
然后只需创建
文件
对象:

File file = new File(filename);
您需要了解,
文件
对象并不表示磁盘上的任何真实数据,实际上它只是一个文件名。该文件甚至不必存在。如果您想实际写入数据,这就是
FileOutputStream
的用途

编辑:我刚刚发现,您不想先写出数据,但如果要将文件传递给某个需要包含数据的真实文件,则必须这样做


如果您不想这样做,您将不得不使用不同的API,它不希望文件存在。。。根据Qwerky的回答。

您应该使用一个
ZipInputStream
包裹在从
FTPClient
retrieveFileStream(String remote)
返回的
InputStream
周围,您不需要创建
File
对象

如果要保存文件,应将流直接导入
ZipOutputStream

ByteArrayOutputStream out = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(out);

// do whatever with your zip file
相反,如果要打开刚检索到的文件,请使用
ZipInputStream

new ZipInputStream(fileClient.retrieveFileStream(String remote));
只要看一下文件,我想你想要:

ZipInputStream zis = new ZipInputStream( new ByteArrayInputStream( out.toByteArray() ) );

然后从ZipInputStream中读取数据。

正如其他人所指出的,对于您尝试执行的操作,您根本不需要将下载的ZIP“文件”写入文件系统

话虽如此,我想指出你问题中的一个误解,这也反映在一些答案中

在Java中,
文件
对象根本不表示文件。相反,它表示一个文件名或*路径”。虽然此名称或路径通常与实际文件相对应,但情况并非如此

这听起来有点像头发分裂,但是考虑一下这个场景:

File dir = new File("/tmp/foo");
boolean isDirectory = dir.isDirectory();
if (isDirectory) {
    // spend a long time computing some result
    ...
    // create an output file in 'dir' containing the result
}
现在,如果
File
类的实例表示文件系统中的对象,那么您希望创建输出文件的代码能够成功(模块权限)。但实际上,创建可能会失败,因为有人删除了“/tmp/foo”,或者用常规文件替换了它


必须指出的是,
File
类上的一些方法似乎确实假定
File
对象确实对应于一个真正的文件系统实体。例如,获取文件大小或时间戳的方法,或者在目录中列出名称的方法。但是,在每种情况下,指定该方法都会引发异常如果实际文件不存在或请求的操作类型错误。

只需将ByteArrayOutputStream更改为FileOutputStream。

回答得很好。我认为Jack是第一个回答的人,他的回答中包含一些代码,对我有帮助。将鼠标悬停在“1小时前回答”上,工具提示会显示发布时间。