我有一个文件夹,里面有 3 张图片,我希望将其压缩并通过电子邮件发送。我有一个方法可以做到这一点,我已经用它来解决以前的问题,并且效果很好。然而这次它不断生成一个无效的 zip,当我打开 zip 时,它里面只有 1 张图片,大小为 0。 我似乎无法弄清楚为什么。方法是这样的:
//generate the zip file for the picture
String zipFile = context.getExternalFilesDir(null) + "/ArcFlash/Checklist.zip";
String srcDir = context.getExternalFilesDir(null) + "/ArcFlash/CheckListMedia";
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
File srcFile = new File(srcDir);
addDirToArchive(zos, srcFile, context);
这是我的 addDirToArchive
方法,它生成 zip:
private static void addDirToArchive(ZipOutputStream zos, File srcFile, Context ctx)
{
File[] files = srcFile.listFiles();
for (int i = 0; i < files.length; i++)
{
// if the file is directory, use recursion
if (files[i].isDirectory())
{
addDirToArchive(zos, files[i], ctx);
continue;
}
try
{
System.out.println("tAdding file: " + files[i].getName());
// create byte buffer
byte[] buffer = new byte[1024];//2048
FileInputStream fis = new FileInputStream(files[i]);
String target = ctx.getExternalFilesDir(null) + "/";
String oldPath = files[i].getPath();
String newPath = oldPath.replace(target, "");
zos.putNextEntry(new ZipEntry(newPath));
int length;
while ((length = fis.read(buffer)) > 0)
{
zos.write(buffer, 0, length);
}
zos.closeEntry();
// close the InputStream
fis.close();
}
catch (Exception ex)
{
Log.i("customException", "error zipping: " + ex.getMessage());
}
}
}
编辑
最佳答案
使用下面的代码示例,以下是如何执行您想要的操作:
final Path basePath = Paths.get(context.getExternalFilesDir(null));
final Path srcDir = Paths.resolve("ArcFlash/CheckListMedia");
final Path zipFile = Paths.resolve("ArcFlash/Checklist.zip");
final Map<String, Object> env = new HashMap<>();
env.put("create", "true");
final URI zip = URI.create("jar:file:" + zipFile.toAbsolutePath().toString());
try (
final FileSystem fs = FileSystems.newFileSystem(zip, env, null);
) {
Files.walkFileTree(srcDir, new CopyFileVisitor(srcDir, fs.getPath("/")));
}
首先,是如何创建 zip 文件的示例:
public final class ZipZip
{
public static void main(final String... args)
throws IOException
{
final Map<String, Object> env = new HashMap<>();
env.put("create", "true");
final URI zip = URI.create("jar:file:/tmp/t.zip");
final Path sourceFile = Paths.get("/tmp/foo.txt");
Files.deleteIfExists(Paths.get("/tmp/t.zip"));
try (
final FileSystem fs = FileSystems.newFileSystem(zip, env, null);
) {
final Path zipdir = fs.getPath("/dir");
Files.createDirectory(zipdir);
final Path zipfile = zipdir.resolve("t.txt");
Files.copy(sourceFile, zipfile);
}
}
}
然后,我最近写了a FileVisitor
to recursively copy a directory ,此处使用;这是它的代码:
public final class CopyFileVisitor
implements FileVisitor<Path>
{
private final Path srcdir;
private final Path dstdir;
public CopyFileVisitor(final Path srcdir, final Path dstdir)
{
this.srcdir = srcdir.toAbsolutePath();
this.dstdir = dstdir.toAbsolutePath();
}
@Override
public FileVisitResult preVisitDirectory(final Path dir,
final BasicFileAttributes attrs)
throws IOException
{
Files.createDirectories(toDestination(dir));
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(final Path file,
final BasicFileAttributes attrs)
throws IOException
{
System.out.printf("%s -> %s\n", file.toAbsolutePath(),
toDestination(file));
Files.copy(file, toDestination(file));
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc)
throws IOException
{
throw exc;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException
{
if (exc != null)
throw exc;
return FileVisitResult.CONTINUE;
}
private Path toDestination(final Path victim)
{
final Path tmp = victim.toAbsolutePath();
final Path rel = srcdir.relativize(tmp);
return dstdir.resolve(rel.toString());
}
}
关于java - 以编程方式生成 zip 会创建无效的 zip[android],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22544083/