bug笔记 - Java --- 网络编程使用BufferedInputStream从缓冲区中读不到数据(浅析BufferedInputStram和BufferedOutputStream的工作机制)

本文通过作者在Java网络编程中遇到的小文件传输失败的bug,深入分析了BufferedInputStream和BufferedOutputStream的工作机制。问题在于未及时刷新缓冲区,解决方法是在每次write()后调用flush()。文章还简要介绍了这两个类的源码,特别是BufferedOutputStream的write()和flush()方法,以及BufferedInputStream的缓冲区读取策略,强调了缓冲技术提高IO效率的重要性。
摘要由CSDN通过智能技术生成

本文主要是从我写Java网络编程时使用BufferedInputStream和BufferedOutputStream的时候遇到的bug, 来分析BufferedInputStream和BufferedOutputStream的工作机制和简单的源码分析.


1. bug描述

最近在写一个Java网络编程的程序, 其中涉及文件的传输问题, 选择使用BufferedInputStream和BufferedOutputStream来作为网络通信读取数据的方式.
在进行测试的时候, 大文件(几百兆甚至上G)是没有问题的, 但是偶然间测试小文件(十几B)总是失败.
大文件传输成功, 小文件传输不成功, 这说明并不是代码逻辑上的问题, 而应该是某个细节的问题.

经过一番仔细考虑, 去看了看BufferedOutputStream和BufferedInputStream的源码, 终于发现是缓冲区的问题.


小伙伴在看了这博客之后说, 只描述bug对一个陌生人来说不具有太大的参考意义. 所以在这里我在”bug描述”中将我的服务端(sender)和客户端(receiver)关于读写数据的核心代码贴出来, 以供大家参考.
因为代码逻辑较为麻烦, 并且牵扯的方法的调用也比较多, 所以对部分代码做一个大概的解释.

代码的出错部分节选:

sender.java代码节选

    public void sendSection() throws IOException {
        // RecieverSectionInfo是一个POJO, 用于存储分片文件的基本信息
        for (RecieverSectionInfo sectionInfo : sectionInfoList) {
            // 发送分片文件正式内容之前先发送一个包头(含有该分片的基本信息)
            String sectionInfoStr = PackageUtil.packageSectionInfo(sectionInfo);
            byte[] sendHeader = PackageUtil.addHeader(sectionInfoStr);
            recieveOutputStream.write(sendHeader);

            // 使用文件随机读写流读取文件内容
            String fileName = sendPath + sectionInfo.getTargetFileName();
            RandomAccessFile randomAccessFile = new RandomAccessFile(fileName, "rw");
            randomAccessFile.seek(sectionInfo.getOffset());

            // 传输分片文件内容
            
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值