我正在尝试将目录从一个区域(sdCard/someFolder)
压缩到第二个目录(sdCard/Download)
,直到.zip文件大小变为5mb。然后,我想创建一个新的.zip
文件,将新文件填充到5mb等等。
目前,我的代码成功地将文件压缩到.zip目录中,但其中一个.zip目录总是会损坏。当我的for循环退出Files[]
的{{1}}时,我会看到这一点,并启动22 objects
Files[]
的下一个目录。我相信我正在丢失一些旧的OutputStreams。在第二次尝试for循环后,4 objects
变为空。任何帮助就足够了。
out.putNextEntry()
}
private static void addDirToArchive(ZipOutputStream out, FileOutputStream destinationDir, File sdCardMNDLogs)
{
File[] listOfFiles = sdCardMNDLogs.listFiles();
BufferedInputStream origin = null;
Log.i(TAG3, "Reading directory: " + sdCardMNDLogs.getName());
try{
byte[] buffer = new byte[BUFFER];
for(int i = 0; i < listOfFiles.length; i++)
{
if(listOfFiles[i].isDirectory())
{
addDirToArchive(out, destinationDir, listOfFiles[i]);
continue;
}
try
{
FileInputStream fis = new FileInputStream(listOfFiles[i]);
origin = new BufferedInputStream(fis,BUFFER);
ZipEntry ze = new ZipEntry(listOfFiles[i].getName());
if(currentZipFileSize >= EMAIL_SIZE)
{
out.close();
Log.d(emailTAG, "Creating new zipfile: /Download/MND/nwdLogs_" + i);
out = new ZipOutputStream(new FileOutputStream(new File(sdCard.getAbsolutePath() + "/Download/MND/nwdLogs_ " + i + ".zip")));
currentZipFileSize = 0;
}
out.putNextEntry(ze);
int length;
Log.i(TAG3, "Adding file: " + listOfFiles[i].getName());
while((length = origin.read(buffer, 0, BUFFER)) != -1)
{
out.write(buffer, 0, length);
}
out.closeEntry();
origin.close();
currentZipFileSize = currentZipFileSize + ze.getCompressedSize();
}
catch(IOException ioe)
{
Log.e(TAG3, "IOException: " + ioe);
}
}
}
finally
{
try {
out.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
答案 0 :(得分:2)
我怀疑问题是您在打开下一个ZIP文件之前没有调用out.close()
。我的理解是ZIP的索引仅在ZIP关闭时写入,因此如果您忽略关闭索引将会丢失:因此损坏。
另请注意,您无需关闭fis
和origin
。只需关闭origin
...即可关闭fis
。
更新 - 修复原始关闭错误后,还有更多内容:
您添加了finally
块以关闭out
。那是错的。您不希望addDirToArchive
关闭out
。这可能是您例外的原因。
完成此操作后会发生一些问题:
if (currentZipFileSize >= EMAIL_SIZE)
{
out.close();
out = new ZipOutputStream(new FileOutputStream(...));
currentZipFileSize = 0;
}
由于out
是本地参数,因此调用者不会看到更改
你做。因此:
当您在来电者中拨打out.close()
时,您可能正在关闭
原始的ZIP(已经关闭)...不是当前的
如果您致电addDirToArchive(out, destinationDir, dirName)
多次,在后续调用中,您可以传递一个封闭的ZIP文件。
您的异常处理被误导(IMO)。如果将文件写入ZIP时出现I / O错误,则不希望记录消息并继续。你想摆脱困境。要么完全崩溃应用程序,要么停止做你正在做的事情。在这种情况下,您&#34;流已关闭&#34;显然是你的代码中的一个错误,你的异常处理实际上告诉应用程序忽略它。
一些建议:
如果您要分担跨多种方法打开和关闭资源的责任,您需要非常小心哪些代码负责关闭什么。你需要了解自己在做什么。
盲目地应用(所谓的)&#34;解决方案&#34; (比如finally
的东西)...&#39;有人说&#34; XXX是最佳实践&#34;或者&#34;总是做XXX&#34; ...会让你陷入困境。你需要1)了解&#34;解决方案&#34; 2,思考关于解决方案是否真正满足您的需求。