如何将一个流读入另一个流?

时间:2022-04-18 23:11:35
FileInputStream in = new FileInputStream(myFile);
ByteArrayOutputStream out = new ByteArrayOutputStream();

Question: How can I read everything from in into out in a way which is not a hand-crafted loop with my own byte buffer?

问题:如何以一种不使用我自己的字节缓冲区的手工循环的方式从内到外读取所有内容?

7 个解决方案

#1


30  

Write one method to do this, and call it from everywhere which needs the functionality. Guava already has code for this, in ByteStreams.copy. I'm sure just about any other library with "general" IO functionality has it too, but Guava's my first "go-to" library where possible. It rocks :)

编写一种方法来执行此操作,并从需要该功能的所有地方调用它。 Guava已经在ByteStreams.copy中拥有了这个代码。我确信任何其他具有“通用”IO功能的库也有它,但是Guava是我的第一个“首选”库。它摇滚:)

#2


19  

In Apache Commons / IO, you can do it using IOUtils.copy(in, out):

在Apache Commons / IO中,您可以使用IOUtils.copy(in,out)来完成:

InputStream in = new FileInputStream(myFile);
OutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);

But I agree with Jon Skeet, I'd rather use Guava's ByteStreams.copy(in, out)

但我同意Jon Skeet,我宁愿使用Guava的ByteStreams.copy(in,out)

#3


11  

So what Guava's ByteStreams.copy(in, out) does:

那么Guava的ByteStreams.copy(in,out)是做什么的:

  private static final int BUF_SIZE = 0x1000; // 4K

  public static long copy(InputStream from, OutputStream to)
      throws IOException {
    checkNotNull(from);
    checkNotNull(to);
    byte[] buf = new byte[BUF_SIZE];
    long total = 0;
    while (true) {
      int r = from.read(buf);
      if (r == -1) {
        break;
      }
      to.write(buf, 0, r);
      total += r;
    }
    return total;
  }

#4


4  

Java 9 (and later) answer:

Java 9(及更高版本)回答:

    in.transferTo(out);

Seems they finally realized that this functionality is so commonly needed that it’d better be built in. The method returns the number of bytes copies in case you need to know.

似乎他们终于意识到这个功能是如此普遍需要它最好被内置。该方法返回你需要知道的字节数。

#5


3  

In my project I used this method:

在我的项目中,我使用了这种方法:

private static void copyData(InputStream in, OutputStream out) throws Exception {
    byte[] buffer = new byte[8 * 1024];
    int len;
    while ((len = in.read(buffer)) > 0) {
        out.write(buffer, 0, len);
    }
}

#6


2  

Alternatively to Guava one could use Apache Commons IO (old), and Apache Commons IOUtils (new as advised in the comment).

作为Guava的替代,可以使用Apache Commons IO(旧版)和Apache Commons IOUtils(评论中建议的新版本)。

#7


0  

I'd use the loop, instead of importing new classes, or adding libraries to my project. The library function is probably also implemented with a loop. But that's just my personal taste.

我使用循环,而不是导入新类,或添加库到我的项目。库函数也可能通过循环实现。但那只是我的个人品味。

However, my question to you: what are you trying to do? Think of the "big picture", if you want to put the entire contents of a file into a byte array, why not just do that? The size of the arrray is file.length(), and you don't need it to dynamically grow, hidden behind a ByteArrayOutputStream (unless your file is shared, and its contents can change while you read).

但是,我的问题是:你想做什么?想想“大局”,如果你想把文件的全部内容放到一个字节数组中,为什么不这样做呢? arrray的大小是file.length(),你不需要它动态增长,隐藏在ByteArrayOutputStream后面(除非你的文件是共享的,它的内容可以在你阅读时改变)。

Another alternative: could you use a FileChannel and a ByteBuffer (java.nio)?

另一种选择:你可以使用FileChannel和ByteBuffer(java.nio)吗?

#1


30  

Write one method to do this, and call it from everywhere which needs the functionality. Guava already has code for this, in ByteStreams.copy. I'm sure just about any other library with "general" IO functionality has it too, but Guava's my first "go-to" library where possible. It rocks :)

编写一种方法来执行此操作,并从需要该功能的所有地方调用它。 Guava已经在ByteStreams.copy中拥有了这个代码。我确信任何其他具有“通用”IO功能的库也有它,但是Guava是我的第一个“首选”库。它摇滚:)

#2


19  

In Apache Commons / IO, you can do it using IOUtils.copy(in, out):

在Apache Commons / IO中,您可以使用IOUtils.copy(in,out)来完成:

InputStream in = new FileInputStream(myFile);
OutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);

But I agree with Jon Skeet, I'd rather use Guava's ByteStreams.copy(in, out)

但我同意Jon Skeet,我宁愿使用Guava的ByteStreams.copy(in,out)

#3


11  

So what Guava's ByteStreams.copy(in, out) does:

那么Guava的ByteStreams.copy(in,out)是做什么的:

  private static final int BUF_SIZE = 0x1000; // 4K

  public static long copy(InputStream from, OutputStream to)
      throws IOException {
    checkNotNull(from);
    checkNotNull(to);
    byte[] buf = new byte[BUF_SIZE];
    long total = 0;
    while (true) {
      int r = from.read(buf);
      if (r == -1) {
        break;
      }
      to.write(buf, 0, r);
      total += r;
    }
    return total;
  }

#4


4  

Java 9 (and later) answer:

Java 9(及更高版本)回答:

    in.transferTo(out);

Seems they finally realized that this functionality is so commonly needed that it’d better be built in. The method returns the number of bytes copies in case you need to know.

似乎他们终于意识到这个功能是如此普遍需要它最好被内置。该方法返回你需要知道的字节数。

#5


3  

In my project I used this method:

在我的项目中,我使用了这种方法:

private static void copyData(InputStream in, OutputStream out) throws Exception {
    byte[] buffer = new byte[8 * 1024];
    int len;
    while ((len = in.read(buffer)) > 0) {
        out.write(buffer, 0, len);
    }
}

#6


2  

Alternatively to Guava one could use Apache Commons IO (old), and Apache Commons IOUtils (new as advised in the comment).

作为Guava的替代,可以使用Apache Commons IO(旧版)和Apache Commons IOUtils(评论中建议的新版本)。

#7


0  

I'd use the loop, instead of importing new classes, or adding libraries to my project. The library function is probably also implemented with a loop. But that's just my personal taste.

我使用循环,而不是导入新类,或添加库到我的项目。库函数也可能通过循环实现。但那只是我的个人品味。

However, my question to you: what are you trying to do? Think of the "big picture", if you want to put the entire contents of a file into a byte array, why not just do that? The size of the arrray is file.length(), and you don't need it to dynamically grow, hidden behind a ByteArrayOutputStream (unless your file is shared, and its contents can change while you read).

但是,我的问题是:你想做什么?想想“大局”,如果你想把文件的全部内容放到一个字节数组中,为什么不这样做呢? arrray的大小是file.length(),你不需要它动态增长,隐藏在ByteArrayOutputStream后面(除非你的文件是共享的,它的内容可以在你阅读时改变)。

Another alternative: could you use a FileChannel and a ByteBuffer (java.nio)?

另一种选择:你可以使用FileChannel和ByteBuffer(java.nio)吗?