Java:具有非静态文件名的Zip文件 [英] Java: Zip file with non-static filename

查看:181
本文介绍了Java:具有非静态文件名的Zip文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这篇文章中发现了这个ZipUtils类:
如何使用java压缩文件夹本身

I found this ZipUtils class on this post: how to zip a folder itself using java

我修改了它,所以我可以传递一个zip文件名。但是,唯一的工作方式是使用硬编码的静态字符串。 zippedFile字符串从数据库中获取。我已经比较了dbZippedFile和hardcodedZippedFile,它们都是完全相同的。也许使用FileOutputStream的非静态字符串有问题吗?此问题只发生在尝试zip目录(一个文件工作正常)时。有没有人知道我在做错什么或有一个很好的选择?

I modified it so I could pass a zip file name. However, the only way it works is with a hardcoded static string. The zippedFile string is grabbed from the database. I have compared the dbZippedFile and hardcodedZippedFile and they are both identical... Perhaps there is an issue with using a non-static string with FileOutputStream? This problem only occurs when trying to zip directories (one file works fine). Does anyone know what I am doing wrong or have a good alternative?

它永远不会出错。它只是无法创建文件。
在代码片段中,如果将zippedFile.getPath()替换为硬编码的字符串表示形式(即D:\\dir\\\\file.zip),则它将起作用。

It never throws an error. It just fails to create the file. In the code snippet, if you replace zippedFile.getPath() with the hardcoded string representation (i.e. "D:\\dir\\file.zip") it works.

代码:

 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());
}
}    


推荐答案

大概数百种方法可以根据您的需要进行修复,但从我的角度来看,您想要做的就是将将此文件夹压缩到此zip文件尽可能少的代码行...

There are probably hundreds of ways you could fix this depending on your needs, but from my perspective, what you want to be able to do is say "Zip this folder to this zip file" in as few lines of code as possible...

为此,我可以改变代码,让你做一些类似...

To this end, I could alter the code to allow you to do something like...

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

使用文件不会有歧义对参数的含义。这种机制也意味着您可以根据需要一次又一次地调用 zipIt ,而无需创建新的 ZipUtils

The use of File leaves no ambiguity as to the meaning of the parameters. This mechanism also means that you can call zipIt again and again and again based on your needs, without having to create a new instance of ZipUtils

这将需要对基础代码进行一些修改,因为它假定文件的 String 值路径,坦白说只是令人生畏,因为您真正想要的所有信息可以从文件对象IMHO更容易地获得。这也意味着您不需要维护对源路径的引用,超出了 zipIt 方法的范围

This will require some modification to the base code, as it assumes String values for the file paths, which frankly is just maddening, as all the information you really want can be more easily obtained from the File object - IMHO. This also means that you don't need to maintain a reference to the source path at all, beyond the scope of the zipIt method

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);
            }
        }
    }
}

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

ps- You public static void main, isn't a valid "main entry point", it should be public static void main(String[] args) ;)

所以,根据你的代码段,你可以简单地做一些...

So, based on your code snippet, you could simply do something like...

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);

这篇关于Java:具有非静态文件名的Zip文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆