-3

我正在尝试从 ByteArrayOutputStream 创建单独的文件(这里 byteOut 是我的 ByteOutputStream)。以下代码完成了这项工作

        final InputStream targetStream = new ByteArrayInputStream(byteOut.toByteArray());
        final File destDir = new File(System.getProperty("user.dir"));
        final byte[] buffer = new byte[1024];
        ZipInputStream zis = new ZipInputStream(targetStream);
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            File newFile = new File(destDir, zipEntry.getName());
            FileOutputStream fos = new FileOutputStream(newFile);
            int len;
            while ((len = zis.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }
            fos.close();
            zipEntry = zis.getNextEntry();
        } 

但是我想优化代码,我尝试像这样使用 IOUtils.copy

        final InputStream targetStream = new ByteArrayInputStream(byteOut.toByteArray());
        final File destDir = new File(System.getProperty("user.dir"));
        ZipInputStream zis = new ZipInputStream(targetStream);
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            File newFile = new File(destDir, zipEntry.getName());
            try(InputStream is = new FileInputStream(newFile);
                    OutputStream fos = new FileOutputStream(newFile)) {
                IOUtils.copy(is, fos);
            }
            zipEntry = zis.getNextEntry();
        }

但是文件的内容没有被复制,并且在第二次迭代中我也得到了 FileNotFoundException。我究竟做错了什么?

4

1 回答 1

1

这是更通用的 Path & Files 类的用例。使用 zip 文件系统,它成为高级复制。

    Map<String, String> env = new HashMap<>(); 
    //env.put("create", "true");
    URI uri = new URI("jar:file:/foo/bar.zip");       
    FileSystem zipfs = FileSystems.newFileSystem(uri, env);

    Path targetDir = Paths.get("C:/Temp");

    Path pathInZip = zipfs.getPath("/");
    Files.list(pathInZip)
         .forEach(p -> {
             Path targetP = Paths.get(targetDir, p.toString();
             Files.createDirectories(targetP.getParent());
             Files.copy(p, targetP);
         }); 

使用底层 Input/OutputStream 必须确保is没有关闭,恢复到库 (IOUtils) / InputStream.transferTo(OutputStream) 和所有这些细节。

于 2020-08-19T14:02:55.317 回答