从事Java开发的一个常见局限是,很多开发者将自身局限在B/S架构的服务端,而缺乏对C/S架构中客户端技术或其他系统层面的广泛了解。要真正掌握Java IO,首先必须理解IO本身的基本原理。建议阅读《现代操作系统》的前三章,深入理解计算机的三大核心组件:CPU、内存和IO(输入/输出)。事实上,日后工作中遇到的绝大多数性能优化问题,都可以从这三方面入手分析和解决。

为什么需要多线程?如果所有操作都只在CPU和内存中执行,其实并不需要多线程。多线程的出现,本质上是因为IO操作速度较慢,为了在等待IO时充分利用CPU资源,才需要并发执行其他任务。在建立这一共识的基础上,我们再进一步探讨IO。

IO可分为网络IO和文件IO。本文暂不讨论网络IO,主要聚焦于文件IO。文件IO的核心其实只需掌握两个类:FileInputStream(用于字节流的顺序读取)和RandomAccessFile(支持随机读取)。至于Reader、BufferedInputStream等,实质上都是在前者基础上进行的封装——例如将字节转换为字符,或添加字节数组作为缓冲池。

与其听信各种高赞回答中模糊的说法,不如自己动手写一个程序:尝试将一个500MB的JPG格式图片转换为PNG格式,并尽力将性能优化到极致。通过这个过程,你会深刻理解到:FileInputStream 本身并不慢,通过自定义字节数组同样可以实现类似BufferedInputStream的缓冲效果,甚至发现使用8192字节的缓冲区时读取速度最快(这与计算机组成原理中“页大小”的概念密切相关)。而RandomAccessFile 在实际应用中适用范围更广。一旦文件被预读,操作系统会自动缓存其内容,很多时候并不需要额外添加缓冲机制。

如果感兴趣,你还可以尝试自己实现一个BufferedRandomAccessFile,这将进一步加深对IO机制的理解。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐