Java 如何按月筛选目录中的文件,根据月份对其进行压缩,重命名它们,将它们放在包含ZipFile的文件夹中?

Java 如何按月筛选目录中的文件,根据月份对其进行压缩,重命名它们,将它们放在包含ZipFile的文件夹中?,java,directory,zip,filtering,file-rename,Java,Directory,Zip,Filtering,File Rename,我有一个包含1000多个文件的目录,我需要根据月份对它们进行压缩,重命名它们并将压缩后的文件放在文件夹中。我通常是手工操作,但我厌倦了这种方式。我写了一个程序,可以重命名文件并将它们放在一个新文件夹中,但我不知道如何在Windows10上使用java按月过滤或压缩它们 String path = "C:\\\\Users\\\\srs\\\\Desktop\\\\Test\\notProcessed"; File[] filelist = new File(pa

我有一个包含1000多个文件的目录,我需要根据月份对它们进行压缩,重命名它们并将压缩后的文件放在文件夹中。我通常是手工操作,但我厌倦了这种方式。我写了一个程序,可以重命名文件并将它们放在一个新文件夹中,但我不知道如何在Windows10上使用java按月过滤或压缩它们

        String path = "C:\\\\Users\\\\srs\\\\Desktop\\\\Test\\notProcessed";

        File[] filelist = new File(path).listFiles();

        for (File file : filelist) {
            Date d = new Date(file.lastModified());
            Calendar c = Calendar.getInstance();
            c.setTime(d);
            int iyear = c.get(Calendar.YEAR);
            int imonth = c.get(Calendar.MONTH);
            String syear = Integer.toString(iyear);
            String smonth = Integer.toString(imonth);
            System.out.println(syear + "_" + smonth);
            String destpath = "C:\\\\Users\\\\srs\\\\Desktop\\\\Test\\notProcessed\\\\TestZip\\\\";
            byte[] buffer = new byte[1024];
            try {
                FileOutputStream fos = new FileOutputStream(destpath + syear + "_" + smonth + ".zip");
                ZipOutputStream zos = new ZipOutputStream(fos);
                System.out.println("Output to Zip : " + file);
                System.out.println("File Added : " + file.getAbsolutePath().toString());
                ZipEntry ze = new ZipEntry(file.getName());
                zos.putNextEntry(ze);
                FileInputStream in = new FileInputStream(file);
                int len;
                while ((len = in.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }
                in.close();
                zos.closeEntry();
                zos.close();
                System.out.println("Done");
            } catch (IOException ex) {
                ex.printStackTrace();
            }

        }

    }
这就是我到目前为止所做的。程序运行了,但没有给出所需的结果。它应该给我3个zip文件夹(基于
lastModified()
)2019\u 07、2019\u 08、2019\u 09,但我得到的是2019\u 06、2019\u 07、2019\u 08、2019\u 10,每个文件夹中只有一个文件。

分组 您当前正在使用
文件
API和旧的日期-时间API(例如
日期
)。我建议你:

  • 使用
    java.nio.file
    API而不是
    file
    API
  • 使用Java8中添加的
    java.time
    API,而不是旧的日期时间API。
    • 这一点特别重要。在创建新代码时,应该不惜一切代价避免使用旧的日期时间API
  • 根据我对您的问题的理解,您希望按文件上次修改的年份和月份对文件进行分组,并将其放入自己的ZIP文件中。对于分组,我们可以使用类和方法。下面是一个例子:

    映射组文件(路径目录,int深度)引发IOException{
    映射结果=新的HashMap();
    Files.walkFileTree(dir,Set.of(),depth,new SimpleFileVisitor()){
    private final ZoneId systemZone=ZoneId.systemDefault();
    private final YearMonth currentYearMonth=YearMonth.now();
    @凌驾
    公共文件VisitResult visitFile(路径文件,基本文件属性属性属性){
    YearMonth YearMonth=GetYearMonthFastModifiedTime(属性);
    if(yearMonth.isBefore(currentYearMonth)){
    computeIfAbsent(yearMonth,k->newArrayList()).add(file);
    }
    返回FileVisitResult.CONTINUE;
    }
    private YearMonth GetYearMonthFastModifiedTime(基本文件属性属性属性属性){
    Instant lastModInstant=attrs.lastModifiedTime().toInstant();
    返回YearMonth.from(LocalDate.ofInstant(lastModInstant,systemZone));
    }
    });
    返回结果;
    }
    
    以上是使用系统默认时区。我还添加了一个选项,用于指定搜索文件树时要转到的最大深度(根目录为
    dir
    )。如果您只想查找属于
    dir
    的直接子文件,请使用
    1
    。此外,如果最大深度始终为
    1
    ,则可以使用
    DirectoryStream
    而不是
    FileVisitor

    请注意,要获取
    路径
    实例,可以调用
    文件#toPath()
    。由于我们试图避免使用
    文件
    类,因此最好使用(或者,如果不使用Java 11+,
    路径#get
    )。例如:

    Path Path=Path.of(“C:”、“用户”、“srs”、“桌面”、“测试”、“未处理”);
    
    上述
    路径
    将与默认的
    文件系统
    相关联


    创建ZIP 一旦您按照上次修改时间的
    YearMonth
    对文件进行分组,您需要将它们放入ZIP文件中。在JDK中,至少有两个用于创建ZIP文件的选项:

  • java.util.zip
    API
  • (通过
    java.nio.file
    API使用)
  • 我相信,第一个选项可以让您更好地控制压缩过程。但是,第二个选项允许您以透明的方式将ZIP文件与任何其他文件系统一样对待。对于这个答案,我将展示第二个选项的示例:

    列出压缩文件(路径zipDir,映射组文件)
    抛出IOException{
    List zipFiles=newarraylist(groupedFiles.size());
    DateTimeFormatter zipFilenameFormatter=DateTimeFormatter.of模式(“uuuu_MM.zip”);
    对于(Map.Entry:groupedFiles.entrySet()){
    Path zipFile=zipDir.resolve(zipFilenameFormatter.format(entry.getKey());
    添加(zipFile);
    URI=URI.create(“jar:+zipFile.toUri());
    Map env=Map.of(“创建”,Boolean.toString(Files.notExists(zipFile));
    try(FileSystem-zipFileSystem=FileSystems.newFileSystem(uri,env)){
    路径zipRoot=zipFileSystem.getRootDirectories().iterator().next();
    对于(路径源:entry.getValue()){
    move(source,zipRoot.resolve(source.getFileName().toString());
    }
    }
    }
    返回拉链;
    }
    
    我之所以使用,是因为您的问题指出ZIP文件的文件名应该是
    year\u month.ZIP
    (带下划线)。
    YearMonth#toString()
    方法将返回
    YearMonth
    (带破折号),因此
    DateTimeFormatter
    用于用下划线分隔年和月。如果您不介意破折号,那么只需使用
    yearMonth.toString()+“.zip”
    即可创建文件名

    上面的代码用于将文件实际添加到ZIP文件中。文件将被压缩。注意:如果ZIP文件中已存在具有该名称的条目,则此操作将失败,但您可以使用
    REPLACE\u EXISTING
    更改此操作。调用
    #move
    将删除源文件;如果不是这样的话,请考虑使用<代码>文件>拷贝<代码>。
    注意:我使用
    Path#resolve(String)
    而不是
    Path#resolve(Path)
    ,因为根据我的经验,后者要求两个
    Path
    实例属于同一个提供者。

    请添加有关操作系统的信息。另外,给我们看看你的程序代码,也许有人可以添加这个功能。你说的“按月过滤”是什么意思?是否只应包括某个月之前的文件?或者,您是否按月对文件进行分组,每个分组都有自己的ZIP文件?
    是如何切割的