以代码名One合并存储文件,我阐述了此解决方案:
/**
* Merges the given list of Storage files in the output Storage file.
* @param toBeMerged
* @param output
* @throws IOException
*/
public static synchronized void mergeStorageFiles(List<String> toBeMerged, String output) throws IOException {
if (toBeMerged.contains(output)) {
throw new IllegalArgumentException("The output file cannot be contained in the toBeMerged list of input files.");
}
// Note: the temporary file used for merging is placed in the FileSystemStorage because it offers the method
// openOutputStream(String file, int offset) that allows appending to a stream. Storage doesn't have a such method.
long writtenBytes = 0;
String tempFile = FileSystemStorage.getInstance().getAppHomePath() + "/tempFileUsedInMerge";
for (String partialFile : toBeMerged) {
InputStream in = Storage.getInstance().createInputStream(partialFile);
OutputStream out = FileSystemStorage.getInstance().openOutputStream(tempFile, (int) writtenBytes);
Util.copy(in, out);
writtenBytes = FileSystemStorage.getInstance().getLength(tempFile);
}
Util.copy(FileSystemStorage.getInstance().openInputStream(tempFile), Storage.getInstance().createOutputStream(output));
FileSystemStorage.getInstance().delete(tempFile);
}
此解决方案基于API FileSystemStorage.openOutputStream(String file, int offset)
,这是我发现的唯一允许将文件内容附加到另一个API的API。
还有其他可用于添加或合并文件的API吗?
谢谢
由于您最终将所有内容复制到Storage
条目,所以我看不到使用FileSystemStorage
作为中间合并工具的价值。
我能想到的唯一原因是输出文件的完整性(例如,如果写入时发生故障),但这也可能在这里发生。您可以通过设置标志来保证完整性,例如创建一个名为“ writeLock”的文件,并在写入成功完成后将其删除。
为清楚起见,我会像这样更简单/更快地进行复制:
try(OutputStream out = Storage.getInstance().createOutputStream(output)) {
for (String partialFile : toBeMerged) {
try(InputStream in = Storage.getInstance().createInputStream(partialFile)) {
Util.copyNoClose(in, out, 8192);
}
}
}