我有一个从文件列表中创建Zip文件的函数。是否可以返回Zip文件而不将其保存在磁盘上?我需要该文件,因为我必须使用zip文件作为另一个函数的参数。我不确定ByteStream对我来说是一个选择。
public File compressFileList(List<File> fileList,String fileName) {
FileOutputStream fileOutputStream=null;
ZipOutputStream zipOutputStream=null;
FileInputStream fileInputStream=null;
String compressedFileName=fileName +".zip";
if(fileList.isEmpty())
return null;
try
{
fileOutputStream = new FileOutputStream(compressedFileName);
zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream));
for (File file: fileList) {
fileInputStream = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(zipEntry);
byte[] tmp = new byte[4*1024];
int size = 0;
while((size = fileInputStream.read(tmp)) != -1){
zipOutputStream.write(tmp, 0, size);
}
zipOutputStream.flush();
fileInputStream.close();
}
zipOutputStream.close();
return compressedFile; //This is what I am missing
}
catch (FileNotFoundException e)
{
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
编辑:添加用例
这个想法是创建一个zip文件并使用Watson的VisualRecognition Service的CreateClassifierOptions方法。
classifierOptions = new CreateClassifierOptions.Builder()
.classifierName("Santa")
.addClass("Santa", new File("C:\\app\\GitRepo\\images\\beagle.zip"))
.negativeExamples(new File("C:\\app\\GitRepo\\images\\nosport.zip"))
.build();
构建器接受zip文件作为参数。
了解
根据Alexandre Dupriez的解释,我认为最好将文件存储在硬盘上的某个位置。
答案 0 :(得分:3)
您应该可以使用ByteArrayOutputStream
代替FileOutputStream
:
zipOutputStream = new ZipOutputStream(new ByteArrayOutputStream());
这里的难点是为使用zip文件的方法提供File
。 java.io.File
没有提供允许您操作内存文件的抽象。
java.io.File
抽象和java.io.FileInputStream
实施
为了简化,如果我们不得不归结File
抽象是什么,我们会将其视为URI
。因此,为了能够构建内存File
,或者至少模仿它,我们需要提供一个URI
,然后由File
的消费者使用阅读其内容。
如果我们查看消费者可能会使用的FileInputStream
,我们可以看到它总是以本机调用结束,这使我们有可能抽象FileSystem
进入 - 记忆文件:
// class java.io.FileInputStream
/**
* Opens the specified file for reading.
* @param name the name of the file
*/
private native void open0(String name) throws FileNotFoundException;
如果有可能让消费者接受InputStream
,那会更容易,但从你的问题陈述中我想这是不可能的。
API调用
您的要求是为Watson Visual API提供File
。
您能否提供您需要致电的API方法?
答案 1 :(得分:1)
public void compressFileList(List<File> fileList, OutputStream outputStream)
throws IOException {
try (ZipOutputStream zipOutputStream =
new ZipOutputStream(new BufferedOutputStream(outputStream));
for (File file: fileList) {
try (FileInputStream fileInputStream = new FileInputStream(file)) {
ZipEntry zipEntry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(zipEntry);
byte[] tmp = new byte[4*1024];
int size = 0;
while((size = fileInputStream.read(tmp)) != -1){
zipOutputStream.write(tmp, 0, size);
}
zipOutputStream.flush();
} catch (FileNotFoundException e) { // Maybe skip not found files.
Logger.log(Level.INFO, "File not found {}", file.getPath());
}
}
}
}
用法:
if (fileList.isEmpty()) {
...
return;
}
try {
compressFileList(fileList, servletRequest.getOutputStream())) {
} catch (FileNotFoundException e) {
...
} catch (IOException e) {
...
}