Java中使用通配符指定文件路径解压Zip文件报错求助
问题:Java中使用通配符指定文件路径解压时触发FileNotFoundException
需要解压指定文件夹中文件名不固定的文件,尝试在路径中使用通配符detailedreport_*.zip,但出现如下错误:
java.io.FileNotFoundException: C:\SAST\Downloaded XML Files\detailedreport_*.zip (文件名、目录名或卷标语法不正确)
原代码如下:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class UnzipFiles { public static void main(String[] args) { String zipFilePath = "C:\\SAST\\Downloaded XML Files\\detailedreport_*.zip"; String zipFilePath2 = "C:\\SAST\\Downloaded XML Files\\detailedreport_*.zip"; String destDir = "C:\\SAST\\Downloaded XML Files\\Unzipped Files"; String destDir2 = "C:\\SAST\\Downloaded XML Files\\Unzipped Files"; unzip(zipFilePath,destDir); unzip2(zipFilePath2,destDir2); } private static void unzip(String zipFilePath,String destDir) { File dir = new File(destDir); // create output directory if it doesn't exist if(!dir.exists()) dir.mkdirs(); FileInputStream fis; //buffer for read and write data to file byte[] buffer = new byte[1024]; try { fis = new FileInputStream(zipFilePath); ZipInputStream zis = new ZipInputStream(fis); ZipEntry ze = zis.getNextEntry(); while(ze != null){ String fileName = ze.getName(); File newFile = new File(destDir + File.separator + fileName); System.out.println("Unzipping to "+newFile.getAbsolutePath()); //create directories for sub directories in zip new File(newFile.getParent()).mkdirs(); FileOutputStream fos = new FileOutputStream(newFile); int len; while ((len = zis.read(buffer)) > 0) { fos.write(buffer, 0, len); } fos.close(); //close this ZipEntry zis.closeEntry(); ze = zis.getNextEntry(); } //close last ZipEntry zis.closeEntry(); zis.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } } private static void unzip2(String zipFilePath2,String destDir2) { File dir2 = new File(destDir2); // create output directory if it doesn't exist if(!dir2.exists()) dir2.mkdirs(); FileInputStream fis2; //buffer for read and write data to file byte[] buffer2 = new byte[1024]; try { fis2 = new FileInputStream(zipFilePath2); ZipInputStream zis2 = new ZipInputStream(fis2); ZipEntry ze2 = zis2.getNextEntry(); while(ze2 != null){ String fileName2 = ze2.getName(); File newFile2 = new File(destDir2 + File.separator + fileName2); System.out.println("Unzipping to "+newFile2.getAbsolutePath()); //create directories for sub directories in zip new File(newFile2.getParent()).mkdirs(); FileOutputStream fos2 = new FileOutputStream(newFile2); int len2; while ((len2 = zis2.read(buffer2)) > 0) { fos2.write(buffer2, 0, len2); } fos2.close(); //close this ZipEntry zis2.closeEntry(); ze2 = zis2.getNextEntry(); } //close last ZipEntry zis2.closeEntry(); zis2.close(); fis2.close(); } catch (IOException e) { e.printStackTrace(); } } }
解决方案
Java的FileInputStream等传统IO类不支持直接解析路径中的通配符,必须先手动匹配符合规则的文件,再逐个处理。以下是优化后的实现:
修改后的完整代码
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class UnzipFiles { public static void main(String[] args) { String targetDir = "C:\\SAST\\Downloaded XML Files"; String destDir = "C:\\SAST\\Downloaded XML Files\\Unzipped Files"; // 筛选符合detailedreport_*.zip格式的文件 try (Stream<Path> paths = Files.list(Paths.get(targetDir))) { paths.filter(path -> path.getFileName().toString().matches("detailedreport_.*\\.zip")) .forEach(path -> unzip(path.toString(), destDir)); } catch (IOException e) { e.printStackTrace(); } } // 统一的解压方法 private static void unzip(String zipFilePath, String destDir) { File dir = new File(destDir); if (!dir.exists()) dir.mkdirs(); byte[] buffer = new byte[1024]; // 使用try-with-resources自动关闭流,避免资源泄漏 try (FileInputStream fis = new FileInputStream(zipFilePath); ZipInputStream zis = new ZipInputStream(fis)) { ZipEntry ze; while ((ze = zis.getNextEntry()) != null) { String fileName = ze.getName(); File newFile = new File(destDir + File.separator + fileName); System.out.println("Unzipping to " + newFile.getAbsolutePath()); // 创建文件的父目录 new File(newFile.getParent()).mkdirs(); try (FileOutputStream fos = new FileOutputStream(newFile)) { int len; while ((len = zis.read(buffer)) > 0) { fos.write(buffer, 0, len); } } zis.closeEntry(); } } catch (IOException e) { e.printStackTrace(); } } }
关键说明
- 通配符匹配:用正则表达式
detailedreport_.*\\.zip匹配文件名,.*代表任意字符序列,\\.是转义的点号(正则中.默认匹配任意字符)。 - 资源管理:使用try-with-resources语法自动关闭流,无需手动调用close方法,避免资源泄漏。
- 代码复用:删除重复的
unzip2方法,统一用unzip处理所有符合条件的文件。
内容的提问来源于stack exchange,提问作者Pooja
相关产品推荐
相关产品推荐

