我有几个zip文件,每个文件都包含几个文件,我想用ZipInputStream类提取这些文件。其中有一些图片。当我尝试使用BufferedOutputStream提取这些图像时,它们会被部分解压缩并且图像不完整。
private void extractArchives() {
ZipInputStream zis;
File archiveDir = new File(
Environment.getExternalStorageDirectory().getAbsolutePath() +
"/archives/");
File[] files = archiveDir.listFiles();
for (int i = 0; i < files.length; ++i)
{
File file = files[i];
try
{
zis = new ZipInputStream(new FileInputStream(file));
ZipEntry ze;
while ((ze = zis.getNextEntry()) != null)
{
BufferedOutputStream bos;
byte[] buffer = new byte[102400];
int count;
while ((count = zis.read(buffer)) != -1)
{
String fileName = ze.getName();
if (fileName.endsWith(".jpg"))
{
path += File.separator + fileName;
bos = new BufferedOutputStream(new FileOutputStream(path));
bos.write(buffer, 0, count);
bos.close();
}
}
}
zis.close();
}
catch(FileNotFoundException e) { continue; }
//If the file is not a zip file or is a directory
catch (IOException e) { continue; }
}
}
上面的代码有什么问题吗?使用BufferedOutputStream会导致此问题吗?我很欣赏任何想法。感谢。
答案 0 :(得分:1)
我根据Erwin的说法修改了方法,现在它可以工作:
private void extractArchives() {
File archiveDir = new File(
Environment.getExternalStorageDirectory().getAbsolutePath() +
"/archives/");
String archivePath = archiveDir.getAbsolutePath();
File[] files = archiveDir.listFiles();
for (int i = 0; i < files.length; ++i)
{
File file = files[i];
if(!file.isDirectory())
{
try {
ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
ZipEntry entry = zis.getNextEntry();
while (entry != null)
{
if(entry.getName().endsWith(".jpg"))
{
String imagePath = themePath + File.separator + entry.getName();
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(imagePath));
byte[] buffer = new byte[4096];
int read = 0;
while ((read = zis.read(buffer)) != -1) bos.write(buffer, 0, read);
imagePath = "";
bos.close();
}
zis.closeEntry();
entry = zis.getNextEntry();
}
zis.close();
}
catch (FileNotFoundException e) {}
catch (IOException e) {}
}
}
}
答案 1 :(得分:0)
专注于遍历zip条目的循环,问题是您从zip条目读取最多102400个字节,然后将其写入新文件。如果将相同的图像文件写入新文件,则下一个最大102400个字节。如果路径名与旧文件相同,则会覆盖旧文件。但由于你经常附加到局部变量'path',我不确定数据的最终位置。
将FileOutputStream的开口拉出内部循环,并继续写入相同的OutputStream,直到您无法从当前ZipEntry读取更多字节。然后才转到下一个ZipEntry和下一个OutputStream。
这是在Java中读取和复制流的标准模式,因此我可以在不具有files
,path
和zis
定义的情况下修复代码,但如果您可以发布一个实际的编译代码示例,以便其他人也可以从中受益。
生产代码中需要的另一项改进是将bos.close()
包装在try / finally块中,以便在从输入读取时出现异常时输出文件也会关闭。
while ((ze = zis.getNextEntry()) != null) {
String fileName = ze.getName();
if (fileName.endsWith(".jpg")) {
String filepath = path + File.separator + fileName;
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filepath));
byte[] buffer = new byte[102400];
int count;
while ((count = zis.read(buffer)) != -1) {
bos.write(buffer, 0, count);
}
bos.close();
}
}