从ByteArrayOutputStream创建文件

huangapple go评论75阅读模式
英文:

Creating files from ByteArrayOutputStream

问题

我正在尝试从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。我做错了什么?

英文:

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?

答案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.toString(), p.getFileName().toString());
         try {
             Files.createDirectories(targetP.getParent());
             Files.copy(p, targetP);
         } catch (IOException e) {
             // Handle IOException
             e.printStackTrace();
         }
     });

使用底层的Input/OutputStream时,必须确保is没有被关闭,可以使用库(例如IOUtils)/ InputStream.transferTo(OutputStream)来处理所有这些细节。

英文:

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

    Map&lt;String, String&gt; env = new HashMap&lt;&gt;(); 
    //env.put(&quot;create&quot;, &quot;true&quot;);
    URI uri = new URI(&quot;jar:file:/foo/bar.zip&quot;);       
    FileSystem zipfs = FileSystems.newFileSystem(uri, env);

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

    Path pathInZip = zipfs.getPath(&quot;/&quot;);
    Files.list(pathInZip)
         .forEach(p -&gt; {
             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.

huangapple
  • 本文由 发表于 2020年8月19日 21:32:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63488150.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定