概述
Java 的 I/O 操作类在包 java.io 下,大概有将近 80 个类,但是这些类大概可以分成四组,分别是:
按处理数据类型来分:字节流和字符流:
- 基于字节操作的 I/O 接口:InputStream 和 OutputStream
- 基于字符操作的 I/O 接口:Writer 和 Reader
按传输数据的方式:磁盘操作和网络操作
- 基于磁盘操作的 I/O 接口:File
- 基于网络操作的 I/O 接口:Socket
按流的方向来分:输入流和输入流
- 要读的话就用输入流,要写的话,就用输出流
前两组主要是根据传输数据的数据格式,后两组主要是根据传输数据的方式,虽然 Socket 类并不在 java.io 包下,但是我仍然把它们划分在一起,因为我个人认为 I/O 的核心问题要么是数据格式影响 I/O 操作,要么是传输方式影响 I/O 操作,也就是将什么样的数据写到什么地方的问题,I/O 只是人与机器或者机器与机器交互的手段,除了在它们能够完成这个交互功能外,我们关注的就是如何提高它的运行效率了,而数据格式和传输方式是影响效率最关键的因素了。
3.什么时候使用字节流?什么时候使用字符流?
首先需要知道的是,任何数据存在硬盘上时,都是以二进制的形式存储的。而通过使用字节流,可以读取任意文件。字节流一次读取一个字节,而字符流使用了字节流读到一个或者多个字节时,去查找指定的编码表,返回对应的编码。所以字符流只能处理纯文本字符数据,而字节流可以处理更多类型的数据,比如图片,视频,音频文件等。因此,只要是纯文本数据处理,优先考虑使用字符流。其他情况就使用字节流。
基于字节的 I/O 操作接口
概述
基于字节的 I/O 操作接口输入和输出分别是:InputStream 和 OutputStream,InputStream 输入流的类继承层次如下图所示:
图 1. InputStream 相关类层次结构(查看大图)
输入流根据数据类型和操作方式又被划分成若干个子类,每个子类分别处理不同操作类型,OutputStream 输出流的类层次结构也是类似,如下图所示:
图 2. OutputStream 相关类层次结构(查看大图)
示例1:使用字节流,读取和存储图片
首先使用输入流读取图片信息,然后通过输出流写入图片信息:
package org.example.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class TestIOStream {
/**
*
* DOC 将F盘下的test.jpg文件,读取后,再存到E盘下面.
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
FileInputStream in = new FileInputStream(new File("F:\\test.jpg"));// 指定要读取的图片
File file = new File("E:\\test.jpg");
if (!file.exists()) {
// 如果文件不存在,则创建该文件
file.createNewFile();
}
FileOutputStream out = new FileOutputStream(new File("E:\\test.jpg"));// 指定要写入的图片
int n = 0;// 每次读取的字节长度
byte[] bb = new