【问题标题】:Java: Zip file with non-static filenameJava:具有非静态文件名的 Zip 文件
【发布时间】:2015-04-28 05:16:50
【问题描述】:

我在这篇文章中找到了这个 ZipUtils 类: how to zip a folder itself using java

我对其进行了修改,以便可以传递一个 zip 文件名。但是,它的唯一工作方式是使用硬编码的静态字符串。 zippedFile 字符串是从数据库中获取的。我已经比较了 dbZippedFile 和 hardcodedZippedFile 并且它们都是相同的......也许在 FileOutputStream 中使用非静态字符串存在问题?仅在尝试压缩目录时才会出现此问题(一个文件可以正常工作)。有谁知道我做错了什么或有一个好的选择?

它永远不会抛出错误。它只是无法创建文件。 在代码 sn-p 中,如果将 zippedFile.getPath() 替换为硬编码的字符串表示形式(即“D:\\dir\\file.zip”),它就可以工作。

代码:

 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
 Date date = new Date();

 String zipName = name+ "_" + dateFormat.format(date) + ".zip";
 zippedFile = new File(archive, zipName);
 if (zippedFile .exists()) {
      zippedFile .delete();
 }
 ZipUtils.main(dirToZip.getPath(), zippedFile.getPath());

类:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipUtils
{

private List<String> fileList;
private static String SOURCE_FOLDER; // SourceFolder path

public ZipUtils()
{
 fileList = new ArrayList<String>();

}

public static void main(String source, String output)
{       
 SOURCE_FOLDER = source;

 //output = "D:\\dir\\file.zip";
 ZipUtils appZip = new ZipUtils();
 appZip.generateFileList(new File(SOURCE_FOLDER));
 appZip.zipIt(output);
}

public void zipIt(String zipFile)
{
 byte[] buffer = new byte[1024];
 String source = "";
 FileOutputStream fos = null;
 ZipOutputStream zos = null;

 try
 {
    try
    {
       source = SOURCE_FOLDER.substring(SOURCE_FOLDER.lastIndexOf("\\") + 1, SOURCE_FOLDER.length());
    }
   catch (Exception e)
   {
      source = SOURCE_FOLDER;
   }
   fos = new FileOutputStream(zipFile);
   zos = new ZipOutputStream(fos);

   System.out.println("Output to Zip : " + zipFile);
   FileInputStream in = null;

   for (String file : this.fileList)
   {
      System.out.println("File Added : " + file);
      ZipEntry ze = new ZipEntry(source + File.separator + file);

      zos.putNextEntry(ze);
      try
      {
         in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
         int len;
         while ((len = in.read(buffer)) > 0)
         {
            zos.write(buffer, 0, len);
         }
      }
      finally
      {
         in.close();
      }
   }

   zos.closeEntry();
   System.out.println("Folder successfully compressed");

}
catch (IOException ex)
{
   ex.printStackTrace();
}
finally
{
   try
   {
      zos.close();
   }
   catch (IOException e)
   {
      e.printStackTrace();
   }
}
}

public void generateFileList(File node)
{

// add file only
if (node.isFile())
{
   fileList.add(generateZipEntry(node.toString()));

}

if (node.isDirectory())
{
   String[] subNote = node.list();
   for (String filename : subNote)
   {
      generateFileList(new File(node, filename));
   }
}
}

private String generateZipEntry(String file)
{
 return file.substring(SOURCE_FOLDER.length() + 1, file.length());
}
}    

【问题讨论】:

  • 嗯,这听起来是个奇怪的问题。 Java 中对字符串的修改并没有真正发生(所有字符串操作都返回一个新字符串),所以我看不出这会有什么不同。您能否发布导致错误的代码以及错误是什么?
  • 显示不起作用的示例,以及您的预期。
  • 以某种方式将源文件引用传递给ZipUtils
  • 我添加了一个代码sn-p和进一步的解释。
  • 在您更新的问题中,您似乎将要压缩的源目录与输出 zipfile 混淆了

标签: java directory zip zipfile


【解决方案1】:

根据您的需要,您可能有数百种方法可以解决此问题,但从我的角度来看,您希望能够用尽可能少的代码行说“将此文件夹压缩到此 zip 文件” ...

为此,我可以更改代码以允许您执行类似...

ZipUtils appZip = new ZipUtils();
appZip.zipIt(new File(source), new File(output));

File 的使用不会使参数的含义产生歧义。这种机制也意味着您可以根据自己的需要一次又一次地调用zipIt,而无需创建ZipUtils的新实例

这将需要对基本代码进行一些修改,因为它假定文件路径为String 值,坦率地说这简直令人抓狂,因为您真正想要的所有信息都可以从File 对象中更容易地获得 -恕我直言。这也意味着您根本不需要维护对源路径的引用,超出了zipIt 方法的范围

public static class ZipUtils {

    private final List<File> fileList;

    private List<String> paths;

    public ZipUtils() {
        fileList = new ArrayList<>();
        paths = new ArrayList<>(25);
    }

    public void zipIt(File sourceFile, File zipFile) {
        if (sourceFile.isDirectory()) {
            byte[] buffer = new byte[1024];
            FileOutputStream fos = null;
            ZipOutputStream zos = null;

            try {

                String sourcePath = sourceFile.getPath();
                generateFileList(sourceFile);

                fos = new FileOutputStream(zipFile);
                zos = new ZipOutputStream(fos);

                System.out.println("Output to Zip : " + zipFile);
                FileInputStream in = null;

                for (File file : this.fileList) {
                    String path = file.getParent().trim();
                    path = path.substring(sourcePath.length());

                    if (path.startsWith(File.separator)) {
                        path = path.substring(1);
                    }

                    if (path.length() > 0) {
                        if (!paths.contains(path)) {
                            paths.add(path);
                            ZipEntry ze = new ZipEntry(path + "/");
                            zos.putNextEntry(ze);
                            zos.closeEntry();
                        }
                        path += "/";
                    }

                    String entryName = path + file.getName();
                    System.out.println("File Added : " + entryName);
                    ZipEntry ze = new ZipEntry(entryName);

                    zos.putNextEntry(ze);
                    try {
                        in = new FileInputStream(file);
                        int len;
                        while ((len = in.read(buffer)) > 0) {
                            zos.write(buffer, 0, len);
                        }
                    } finally {
                        in.close();
                    }
                }

                zos.closeEntry();
                System.out.println("Folder successfully compressed");

            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    protected void generateFileList(File node) {

        // add file only
        if (node.isFile()) {
            fileList.add(node);

        }

        if (node.isDirectory()) {
            File[] subNote = node.listFiles();
            for (File filename : subNote) {
                generateFileList(filename);
            }
        }
    }
}

ps- 你public static void main,不是一个有效的“主入口点”,它应该是public static void main(String[] args) ;)

因此,根据您的代码 sn-p,您可以简单地执行类似...

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
Date date = new Date();

String zipName = name+ "_" + dateFormat.format(date) + ".zip";
zippedFile = new File(archive, zipName);
if (zippedFile exists()) {
    zippedFile.delete();
}

ZipUtils zu = new ZipUtils();
zu.zipIt(dirToZip, zippedFile);

【讨论】:

  • 这绝对是一个更好的实现。但是,它并没有解决我原来的问题。 zu.zipIt(new File(source), new File(output)) 不会创建 zip 文件。但是, zuzipIt(new File(source), new File("D:\\dir\\file.zip")) 可以。即使 output == "D:\\dir\\file.zip".
  • 这没有意义,两者都是String 值。 output 等于什么?
  • 我知道!输出 == "D:\\dir\\file.zip"。现在,如果我设置 output = "D:\\dir\\file.zip"。然后运行 ​​zu.zipIt(new File(source), new File(output))。有用。但是,如果无论如何修改了输出,它将不再起作用。
  • “但是,如果无论如何修改了输出,它就不再起作用了”“修改”是什么意思?
  • 如果ZipUtil 有问题,那么两者都不起作用。如果没有有关您正在使用的值的更多信息,我不确定您希望我如何为您调试问题:P。问题不在于实用程序,而在于您直接或间接传递的值(即,路径不存在,文件被锁定或您无权写入该位置)...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-18
  • 2017-12-23
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多