自学内容网 自学内容网

文件读写操作:write(buffer)方法可能没有完全写出buffer里的数据的情况

write(buffer)方法,并不会确保把buffer的所有数据都写完出去,出现在以下情况:

通常取决于流的类型以及底层的实现,

文件输出流 (FileOutputStream)

  • 通常来说,FileOutputStream 会将数据直接写入文件,并且它会阻塞,直到所有数据都写入文件。这个过程通常是同步的,因此 write() 很少会有部分写入的情况。然而,操作系统的文件系统缓存和磁盘的性能可能会影响实际的写入速度。

缓冲输出流 (BufferedOutputStream)

  • BufferedOutputStream 使用了缓冲区,它会将数据批量写入目标设备,通常也是阻塞操作。但是,如果缓冲区写满了,它可能会将缓冲区的数据写入目标设备时未写完全,因此需要多次 write() 调用

网络输出流 (SocketOutputStream / ByteChannel)

  • 对于网络流,尤其是通过 SocketChannel 进行的 I/O 操作,write() 很有可能无法一次性写完缓冲区中的所有数据,因为网络 I/O 是异步和分片的

内存映射文件(MappedByteBuffer

  • 内存映射文件的写入通常是异步的,系统会把数据映射到内存中,实际的磁盘写入可能会延迟进行。

  • write(buffer) 可能无法一次性写完所有数据,尤其是在非阻塞 I/O 和网络 I/O 中。操作系统的 I/O 调度、磁盘或网络设备的性能、操作系统的缓存机制等因素,都会影响写操作的执行。
  • 在进行大数据量的读写时,建议检查 write() 返回的字节数,如果它小于缓冲区的容量,应该继续调用 write() 直到所有数据都写入。
  • 所有的输出流不一定都会有这种问题,但是对于网络流、非阻塞 I/O 和一些异步 I/O 操作,这种情况会更加明显。

 在BytesBuffer.allocateDirecte()中:

 while ((bytesRead = sourceFileChannel.read(buffer)) != -1) {

            //先切换到读模式
            buffer.flip();
            //将缓冲区中的数据写入目标文件
            while (buffer.hasRemaining()) {
            //write() 方法并不是总能一次性将整个缓冲区的数据写完,特别是在高并发或网络延迟的情况下。
            //write() 可能会把缓冲区的一部分数据写入文件,如果缓冲区里还有剩余数据,hasRemaining() 会返回 
            //true,并需要再次调用 write(buffer) 直到写完
                destinationFileChannel.write(buffer);//write(buffer)方法,并不会确保把buffer的所有数据都写完出去,所以需要hasRemaining()方法来循环判断是否position<limit,是,返回true
                times++;
            }
            if (times == 8651) {
                int position = buffer.position();
                int limit = buffer.limit();
                System.out.println("position" + position);
                System.out.println("limit" + limit);
            }
            buffer.clear();//清空缓冲区,准备下一次读取
            if (times == 8651) {
                int limit = buffer.limit();
                int position = buffer.position();
                System.out.println("position" + position);
                System.out.println("limit" + limit);
            }

        }

 

ByteBuffer buffer = ByteBuffer.allocate(4096);
int bytesRead;
while ((bytesRead = sourceFileChannel.read(buffer)) != -1) {
    buffer.flip();
    while (buffer.hasRemaining()) {
        int bytesWritten = destinationFileChannel.write(buffer);
        // 如果写入的字节数小于缓冲区剩余字节数,说明并没有完全写完所有数据
        System.out.println("Written bytes: " + bytesWritten);
    }
    buffer.clear();
}


原文地址:https://blog.csdn.net/m0_70630103/article/details/143628210

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!