为什么要将偏移量参数传递给Java BufferedOutputStream.write?

为什么要将偏移量参数传递给Java BufferedOutputStream.write?,java,file-io,Java,File Io,我不太明白您为什么要通过方法public void write(byte[]b,int off,int len)将offset参数传递给Java BufferedOutputStream.write?您可能希望从b参数的非零偏移量开始的用例是什么?即使你能做到,我也不明白你为什么要这么做。据我所知,99%的时间里使用它是不必要的?我实际使用过这个API,它用于一个高速I/O,它重用一个字节[]缓冲区来读取数据,然后将其写出来,但是跳过了负载的某些部分。我实际使用过这个API,这是一个高速I/O,

我不太明白您为什么要通过方法
public void write(byte[]b,int off,int len)将offset参数传递给Java BufferedOutputStream.write
?您可能希望从b参数的非零偏移量开始的用例是什么?即使你能做到,我也不明白你为什么要这么做。据我所知,99%的时间里使用它是不必要的?

我实际使用过这个API,它用于一个高速I/O,它重用一个
字节[]
缓冲区来读取数据,然后将其写出来,但是跳过了负载的某些部分。

我实际使用过这个API,这是一个高速I/O,它重复使用单个
字节[]
缓冲区读入数据,然后将其写出,但跳过了负载的某些部分。

假设我有一个包含图像的20M字节数组,我想通过网络发送该图像的数据。(假设我正在编写一个HTTP服务器。)网络缓冲区只有这么大——我可能想用更易于管理的卡盘将图像数据写入TCP管道。(4k?)

通过设置偏移量,可以避免我需要进行大量阵列拷贝。所以我可以这样使用它:

byte[] image = loadImage();
int chunkSize = 4096; // 4k
int chunks = image.length / chunkSize;
for (int i=0; i<chucks; ++i) {
  os.write(image, i*chunkSize, chunkSize);
}
byte[]image=loadImage();
int chunkSize=4096;//4k
int chunks=image.length/chunkSize;

对于(int i=0;i假设我有一个包含图像的20M字节数组,我想通过网络发送该图像的数据。(假设我正在编写HTTP服务器。)网络缓冲区只有这么大-我可能想用更易于管理的卡盘将图像数据写入TCP管道。(4k?)

通过使用该偏移量,我不必进行大量阵列复制。因此,我可以这样使用它:

byte[] image = loadImage();
int chunkSize = 4096; // 4k
int chunks = image.length / chunkSize;
for (int i=0; i<chucks; ++i) {
  os.write(image, i*chunkSize, chunkSize);
}
byte[]image=loadImage();
int chunkSize=4096;//4k
int chunks=image.length/chunkSize;

对于(int i=0;i当需要写入的字节数组中的数据不在数组的开头时。使用该方法时,使用非零秒参数将数据放入数组。如果您是C/C++程序员,则相应的方法将使用
char*
len
,但不使用偏移量原因偏移可以通过
ptr+offset
轻松完成。这在Java中是无法完成的,因此为了防止需要将字节复制到另一个缓冲区,JDK中接受
字节[]
的大多数方法都会有一个接受
字节[]的重载,offset,len
。当需要写入的字节数组中的数据不在数组的开头时。当您使用该方法时,使用非零秒参数将数据放入数组。如果您是C/C++程序员,则相应的方法将采用
字符*
len
,但不是偏移,因为偏移很容易用
ptr+offset
完成。这在Java中是无法完成的,因此为了防止需要将字节复制到另一个缓冲区,JDK中接受
字节[]
的大多数方法都会有一个接受
字节[]的重载,offset,len
。另一种情况是,如果您能够刷新一些已处理的数据,则需要执行此操作。因此,例如,如果您正在压缩一个10gb的文件,您可能只需要并且希望一次在内存中保存1M的文件。您可以在仍然支持的情况下,将其中的一部分放入,开始放气,并开始发送结果访问。不再需要将整个10g存储在内存中。您肯定不想这样做。您应该在一次调用中写入整个阵列。TCP将完成所有必要的管理。@keredson好的,我想我明白您的意思了,尽管您的用例已经由TCP层处理了,不是吗?例如,这个家伙使用了非0偏移量:我希望你理解我的问题仍然在哪里?@djangofan这正是我的观点。这个例子是人为的,实践不佳。网络缓冲区甚至存在的事实与
OutputStream.write()的操作无关
:它被定义为阻塞,直到所有内容都被写入。编写自己的循环来完成它已经完成的工作是完全没有意义的,而且可能会适得其反。@Djangfan另一个答案就足够了,但我要补充的是,
offset
参数在我曾经编写的Java I/O代码的99%中为零,如果不是99.99%,则为0呃二十年的时间。它之所以存在是因为它必须存在是为了完整性,但实际上它很少被使用。另一种情况是,如果你能够清除一些处理过的数据,你会想这样做。因此,例如,如果你正在压缩一个10gb的文件,你可能只需要并且希望一次在内存中有1M的数据。你可以你可以输入一部分,开始放气,然后在处理过程中开始发送结果。不需要将整个10g存储在内存中。你肯定不想这样做。你只需在一次调用中写入整个数组。TCP将完成所有必要的管理。@keredson好的,我想我明白你所说的要点了虽然您的用例已经由TCP层处理了,不是吗?例如,这家伙使用了一个非0偏移量:我希望您理解我的问题仍然在哪里?@djangofan这正是我的观点。这个例子是人为的,实践很差。网络缓冲区甚至存在的事实与
OutputStre的操作无关am.write()
:它被定义为阻塞,直到所有内容都被写入。编写自己的循环来完成它已经完成的工作是完全没有意义的,而且可能会适得其反。@Djangfan另一个答案就足够了,但我要补充的是,
offset
参数在我曾经编写的Java I/O代码的99%中为零,如果不是99.99%,则为0呃二十年的时间。它在那里是因为它必须在那里才能完整,但在实践中它很少被使用。谢谢你的简单,到