我正在从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);
有什么想法吗?
答案 0 :(得分:4)
您应该使用从ZipInputStream
InputStream
返回的FTPClient
开始retrieveFileStream(String remote)
。
答案 1 :(得分:3)
您无需创建File
对象。
如果要保存文件,则应将流直接传送到ZipOutputStream
ByteArrayOutputStream out = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(out);
// do whatever with your zip file
相反,如果要打开刚刚检索到的文件,请使用ZipInputStream
:
new ZipInputStream(fileClient.retrieveFileStream(String remote));
即可
答案 2 :(得分:2)
我想你想要:
ZipInputStream zis = new ZipInputStream( new ByteArrayInputStream( out.toByteArray() ) );
然后从ZipInputStream中读取您的数据。
答案 3 :(得分:1)
好吧,你可以创建一个FileOutputStream
,然后从中写下数据:
FileOutputStream fos = new FileOutputStream(filename);
try {
out.writeTo(fos);
} finally {
fos.close();
}
然后只需创建File
对象:
File file = new File(filename);
您需要了解File
对象不代表磁盘上的任何实际数据 - 它只是一个文件名,实际上。该文件甚至不必存在。如果你想实际写数据,那就是FileOutputStream
的用途。
编辑:我刚刚发现你不想先写出数据 - 但这就是你得到要做的事情,如果你要将文件传递给需要带有数据的真实文件的东西。
如果您不想这样做,则必须使用不期望文件存在的其他API ...根据Qwerky的回答。
答案 4 :(得分:1)
正如其他人所指出的,对于您要做的事情,您根本不需要将下载的ZIP“文件”写入文件系统。
话虽如此,我想在你的问题中指出一个误解,这也反映在一些答案中。
在Java中,File
对象根本不代表文件。相反,它表示文件 name 或* path“。虽然此名称或路径通常对应于实际文件,但不一定是这种情况。
这可能听起来有点像分裂,但请考虑这种情况:
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
对象确实对应于真正的文件系统实体。示例是获取文件大小或时间戳或在目录中列出名称的方法。但是,在每种情况下,如果实际文件不存在或者请求的操作类型错误,则指定该方法抛出异常。
答案 5 :(得分:0)
只需将ByteArrayOutputStream更改为FileOutputStream。