简体   繁体   English

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

[英]How to create a java.io.File from a ByteArrayOutputStream?

I'm reading a bunch of files from an FTP. 我正在从FTP读取一堆文件。 Then I need to unzip those files and write them to a fileshare. 然后我需要解压缩这些文件并将它们写入文件共享。

I don't want to write the files first and then read them back and unzip them. 我不想先写文件然后再读取它们并解压缩它们。 I want to do it all in one go. 我想一气呵成。 Is that possible? 那可能吗?

This is my code 这是我的代码

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);

Any ideas? 有任何想法吗?

你应该使用一个ZipInputStream包装从FTPClientretrieveFileStream(String remote)返回的InputStream

You don't need to create the File object. 您不需要创建File对象。

If you want to save the file you should pipe the stream directly into a ZipOutputStream 如果要保存文件,则应将流直接传输到ZipOutputStream

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

// do whatever with your zip file

If, instead, you want to open the just retrieved file work with the ZipInputStream : 相反,如果要打开刚刚检索到的文件,请使用ZipInputStream

new ZipInputStream(fileClient.retrieveFileStream(String remote));

Just read the doc here and here 只需在这里这里阅读文档

I think you want: 我想你想要:

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

Then read your data from the ZipInputStream. 然后从ZipInputStream中读取数据。

Well, you could just create a FileOutputStream and then write the data from that: 好吧,你可以创建一个FileOutputStream ,然后从中写入数据:

FileOutputStream fos = new FileOutputStream(filename);
try {
  out.writeTo(fos);
} finally {
  fos.close();
}

Then just create the File object: 然后只需创建File对象:

File file = new File(filename);

You need to understand that a File object doesn't represent any real data on disk - it's just a filename, effectively. 您需要了解File对象不代表磁盘上的任何实际数据 - 它只是一个文件名,实际上。 The file doesn't even have to exist. 该文件甚至不必存在。 If you want to actually write data , that's what FileOutputStream is for. 如果你想实际写入数据 ,那就是FileOutputStream的用途。

EDIT: I've just spotted that you didn't want to write the data out first - but that's what you've got to do, if you're going to pass the file to something that expects a genuine file with data in. 编辑:我刚刚发现,你不希望将数据先写出来-但是这是你必须做的,如果你要的文件传递的东西,希望在数据真正的文件内容。

If you don't want to do that, you'll have to use a different API which doesn't expect a file to exist... as per Qwerky's answer. 如果您不想这样做,那么根据Qwerky的回答,您将不得不使用期望文件存在的其他API。

As others have pointed out, for what you are trying to do, you don't need to write the downloaded ZIP "file" to the file system at all. 正如其他人指出的那样,对于您要做的事情,您根本不需要将下载的ZIP“文件”写入文件系统。

Having said that, I'd like to point out a misconception in your question, that is also reflected in some of the answers. 话虽如此,我想在你的问题中指出一个误解,这也反映在一些答案中。

In Java, a File object does no really represent a file at all. 在Java中, File对象根本不代表文件。 Rather, it represents a file name or *path". While this name or path often corresponds to an actual file, this doesn't need to be the case. 相反,它表示文件或*路径“。虽然此名称或路径通常对应于实际文件,但不一定是这种情况。

This may sound a bit like hair-splitting, but consider this scenario: 这可能听起来有点像分裂,但请考虑这种情况:

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
}

Now if instances of the File class represented objects in the file system, then you'd expect the code that creates the output file to succeed (modulo permissions). 现在,如果File类的实例表示文件系统中的对象,那么您希望创建输出文件的代码成功(模数权限)。 But in fact, the create could fail because, something deleted the "/tmp/foo", or replaced it with a regular file. 但实际上,创建可能会失败,因为删除了“/ tmp / foo”,或者用常规文件替换它。

It must be said that some of the methods on the File class do seem to assume that the File object does correspond to a real filesystem entity. 必须要说的是File类上的一些方法似乎假设File对象确实对应于真正的文件系统实体。 Examples are the methods for getting a file's size or timestamps, or for listing the names in a directory. 示例是获取文件大小或时间戳或在目录中列出名称的方法。 However, in each case, the method is specified to throw an exception if the actual file does not exist or has the wrong type for the operation requested. 但是,在每种情况下,如果实际文件不存在或者请求的操作类型错误,则指定该方法抛出异常。

只需将ByteArrayOutputStream更改为FileOutputStream即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM