问题
What should be the value of or initialize InputStreamSupplier? I was trying to zip all the files in a directory and that should be fast. So multi threading is the option i'm going for.
public class ScatterSample {
ParallelScatterZipCreator scatterZipCreator = new ParallelScatterZipCreator();
ScatterZipOutputStream dirs = ScatterZipOutputStream.fileBased(File.createTempFile("scatter-dirs", "tmp"));
public ScatterSample() throws IOException {
}
public void addEntry(ZipArchiveEntry zipArchiveEntry, InputStreamSupplier streamSupplier) throws IOException {
if (zipArchiveEntry.isDirectory() && !zipArchiveEntry.isUnixSymlink())
dirs.addArchiveEntry(ZipArchiveEntryRequest.createZipArchiveEntryRequest(zipArchiveEntry, streamSupplier));
else
scatterZipCreator.addArchiveEntry( zipArchiveEntry, streamSupplier);
}
public void writeTo(ZipArchiveOutputStream zipArchiveOutputStream)
throws IOException, ExecutionException, InterruptedException {
dirs.writeTo(zipArchiveOutputStream);
dirs.close();
scatterZipCreator.writeTo(zipArchiveOutputStream);
}
}
FirstMain Class:
public class FirstMain {
public FirstMain() {
// TODO Auto-generated constructor stub
}
public static void compressFolder(String sourceFolder, String absoluteZipfilepath)
{
try
{
ScatterSample scatterSample=new ScatterSample();
File srcFolder = new File(sourceFolder);
if(srcFolder != null && srcFolder.isDirectory())
{
Iterator<File> i = FileUtils.iterateFiles(srcFolder, new String []{"pdf"}, true);
File zipFile = new File(absoluteZipfilepath);
OutputStream outputStream = new FileOutputStream(zipFile);
ZipArchiveOutputStream zipArchiveOutputStream= new ZipArchiveOutputStream(outputStream);
int srcFolderLength = srcFolder.getAbsolutePath().length() + 1; // +1 to remove the last file separator
while(i.hasNext())
{
File file = i.next();
String relativePath = file.getAbsolutePath().substring(srcFolderLength);
InputStreamSupplier streamSupplier=new InputStreamSupplier(){
@Override
public InputStream get() {
// TODO Auto-generated method stub
return null;
}
};
ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(relativePath);
scatterSample.addEntry(zipArchiveEntry, streamSupplier);
}
scatterSample.writeTo(zipArchiveOutputStream);
}
}catch (Exception e) {
e.printStackTrace();
}
}
public static void main( String[] args )
{
compressFolder("C:\\Users\\akatm\\Desktop\\Stuff\\zipdata\\Newtry\\","C:/Users/akatm/Desktop/Stuff/Newtry.zip");
}
}
回答1:
The get()
method must return an InputStream to the file.
You could define an internal class as the following:
static class FileInputStreamSupplier implements InputStreamSupplier {
private Path sourceFile;
FileInputStreamSupplier(Path sourceFile) {
this.sourceFile = sourceFile;
}
@Override
public InputStream get() {
InputStream is = null;
try {
is = Files.newInputStream(sourceFile);
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
}
That you could then invoke as:
scatterSample.addEntry(zipArchiveEntry, new FileInputStreamSupplier(file.toPath());
回答2:
You need to set the compress method in the ZipEntry
ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(relativePath);
zipArchiveEntry.setMethod(ZipArchiveEntry.STORED);
scatterSample.addEntry(zipArchiveEntry, streamSupplier);
if you don't set the compress method, the method throws an exception.
来源:https://stackoverflow.com/questions/41393313/fast-zipping-folder-using-java-parallelscatterzipcreator