-2

I am trying to create separate files from ByteArrayOutputStream (Here byteOut is my ByteOutputStream). The following code does the job

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

But I want to optimize the code, I tried using IOUtils.copy like this

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

But the contents of the file aren't getting copied and I also get a FileNotFoundException in the second iteration. What am I doing wrong?

Bhoomi
  • 17
  • 4
  • Does this answer your question? [How to clone an InputStream?](https://stackoverflow.com/questions/5923817/how-to-clone-an-inputstream) – daniu Aug 19 '20 at 13:36
  • The content of the input stream is not the same. As I am trying to loop through files in zip. Ps : the version of java I am using is 1.8 – Bhoomi Aug 19 '20 at 13:50

1 Answers1

1

This is a use-case for the more generalized Path & Files classes. With a zip file system it becomes a high level copying.

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

Using the underlying Input/OutputStream one must ensure that is is not closed, revert to a library (IOUtils) / InputStream.transferTo(OutputStream) and all those details.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138