java字节数组输出流

wgmfuz8q  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(479)

关闭。这个问题需要细节或清晰。它目前不接受答案。
**想改进这个问题吗?**通过编辑这个帖子来添加细节并澄清问题。

上个月关门了。
改进这个问题
可能是个愚蠢的问题,但字节数组通过 outputstream ? 我在网上找不到关于这个的任何信息。
我发现了很多将数组大小设置为2^x或类似大小的示例。但这样做的目的是什么?

igetnqfo

igetnqfo1#

没有最佳尺寸。outputstream是一个抽象的概念;它的实现有一百万种(不只是“fileoutputstream是一个实现”,而是“fileoutputstream,在openjdk11上,在windows 10上,在这种情况下,使用这个servicepack,使用这个cpu和这么多的系统内存”)。
您看到的原因是为了提高缓冲区效率。发送1字节的问题通常基本上是什么都没有,但有时,发送1字节(或很少)会导致这种恶劣的情况:
发送一个字节。
底层outputstream不是为缓冲该字节而设计的,它没有存储该字节的空间,因此它唯一能做的就是将其向前发送到实际的底层资源。假设outputstream表示文件系统上的一个文件。
克内尔德河也同样适用(大多数操作系统在内部进行缓冲,但您可以在打开文件时要求操作系统不要这样做)。
因此,这一字节现在需要写入磁盘。但是,它是一个ssd,不能对ssd执行此操作,只能一次写入整个单元*。ssd就是这样工作的:你只能写一整块的值。它们不是在一个大盘子里按顺序排列的。
因此,内核读取整个单元,更新正在写入的一个字节,然后将整个单元写回ssd。
你的实际循环确实写了,比如说,大约50000字节,所以一些本应该需要一次ssd读写的东西,现在需要50000次读写,消耗掉ssd单元的寿命,比需要的时间长50000倍。
在网络中也会出现类似的问题(最终发送一个字节, Package 在http报头中, Package 在2个tcp/ip数据包中,导致在网络上为每个字节发送约1000个字节) .write(singleValue) 以及许多其他类似的系统。

为什么这些流不缓冲呢?

因为有些情况下你并不希望他们这么做;有很多理由考虑到特定的效率来编写i/o。

有没有办法让我做点什么?

啊,你真幸运,真的! BufferedWriter 还有朋友( BufferedOutputStream 也存在)围绕底层流和缓冲区:

var file = new FileOutputStream("/some/path");
var wrapped = new BufferedOutputStream(file);
file.write(1); // this is a bad idea
wrapped.write(1); // this is fine

在这里, Package 的写操作不会导致任何事情发生,除了一些内存被推到周围。没有字节被写入磁盘(缺点是如果有人被电力电缆绊倒,它就丢失了)。只有在你关门之后 wrapped ,或呼叫 flush() 在 Package ,或写一些足够数量的字节 wrapped ,将实际向底层流发送一大堆字节。这是你应该使用的,如果使字节数组是笨拙的。为什么要重新发明轮子?

但是我想写入底层的原始流

如果字节数小于一个tcp/ip数据包所能容纳的字节数,那么您使用的字节数就太少了,或者是一个不幸的大小(假设tcp/ip数据包能容纳1000个字节,而您发送1001和1002个字节)。这是一个完整的数据包,然后是一个只有1字节的第二个数据包,效率只有50%。50%的效率仍然比0.1%的效率要好,在这个假设中,一次一个字节的效率可以让你达到这个目标。但是,如果你发送5001字节,那就是5个完整的数据包和一个令人遗憾的1字节数据包,效率为83.35%。不幸的是,它没有接近100,但也没有那么糟糕。这同样适用于磁盘(如果一个ssd单元包含2048个字节,而您发送65537个字节,它的效率仍然是96/7%)。
如果对您自己的java进程的影响是这样的,那么您将使用太多的字节:这将导致过度的垃圾收集,或者更糟糕的是,内存不足错误。
那么“甜点”在哪里呢?要看情况,但是 65536 是常见的,不太可能是'太低'。除非同时运行数千个线程,否则也不会太高。
它通常是2的幂,主要是因为迷信,但也有一些道理:那些潜在的缓冲区的东西通常是2的幂(毕竟计算机是二进制的东西)。因此,如果单元格大小恰好是2048,那么如果发送65536字节(相当于32个单元格的数据量),则效率为100%。
但是,您真正要避免的唯一一件事是,如果您一次向打包(ssd、网络等)底层流写入一个字节,则会出现0.1%的效率。因此,这并不重要,只要它超过2048年左右,你应该已经避免了厄运场景。

  • )我过于简单化了;关键是一个字节的读或写可能需要相当于一整块字节的时间,为了说明原因,我们不能对ssd技术进行深入研究。

相关问题