一、Java标准I/O知识体系图:
二、I/O是什么
I/O 是Input/Output(输入、输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出。
三、Java I/O 用途与对应的流一览
注:粗体为节点流。蓝色为转换流(字节流转为字符流)。
四、流结构介:
Java所有的流类位于java.io包中,都分别继承字以下四种抽象流类型。
1.继承自InputStream/OutputStream的流都是用于向程序中输入/输出数据,且数据的单位都是字节(byte=8bit)。
2.继承自Reader/Writer的流都是用于向程序中输入/输出数据,且数据的单位都是字符(2byte=16bit),如图。
四、流的处理
流分为节点流和处理流两种:
节点流: 从一个特定的数据源读写数据。即节点流是直接操作文件,网络等的流,例如FileInputStream和FileOutputStream,他们直接从文件中读取或往文件中写入字节流。
处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接
五、文件的访问
(1)读取文件
如果你需要在不同端使用读取文件,你可以根据你要读的文件是二进制文件还是文本文件,或者根据你要处理的数据是准备采取字节方式还是字符方式,决定使用 FileInputStream 或者 FileReader。两者支持你从文件开头开始到文件结尾读取一个字节或者字符,也可以将读取的多个字节或字符,写入到内存的字节数组或字符数组。
单字节读取文件示例:
public classtest5 {public static void main(String[] args) throwsException {
String filepath= "test.bin";
java.io.InputStream is= null;try{
is= newFileInputStream(filepath);int data = -1;while ((data = is.read()) != -1) {//-1 表示读取到达文件结尾//操作数据
System.out.print((byte)data + " ");
}
}finally{if (is != null) {
is.close();//关闭流
}
}
}
}
字节数组读取文件示例:
public classtest5 {public static void main(String[] args) throwsException {
String filepath= "test.bin";
java.io.InputStream is= null;try{
is= new BufferedInputStream(new FileInputStream(filepath));//组装BufferedInputStream流,加入缓冲能力
byte[] data = new byte[256];int len = -1;while ((len = is.read(data)) != -1) {//-1 表示读取到达文件结尾//操作数据
for (int i = 0; i < len; i++) {
System.out.print(data[i]+ " ");
}
}
}finally{if (is != null) {
is.close();//关闭流
}
}
}
}
单字符读取文件示例:
public classtest5 {public static void main(String[] args) throwsException {
String filepath= "test.txt";
java.io.Reader r= null;try{
r= newFileReader(filepath);int data = -1;while ((data = r.read()) != -1) {//-1 表示读取到达文件结尾//操作数据
System.out.print((char) data);
}
}finally{if (r != null) {
r.close();//关闭流
}
}
}
}
字符数组读取文件示例:
public classtest5 {public static void main(String[] args) throwsException {
String filepath= "file.txt";
java.io.Reader r= null;try{
r= new BufferedReader(new FileReader(filepath));//组装BufferedReader流,加入缓冲能力
char[] data = new char[256];int len = -1;while ((len = r.read(data)) != -1) {//-1 表示读取到达文件结尾//操作数据
for (int i = 0; i < len; i++) {
System.out.print(data[i]);
}
}
}finally{if (r != null) {
r.close();//关闭流
}
}
}
}
public classtest5 {public static void main(String[] args) throwsException {
String filepath= "file.txt";
java.io.Reader r= null;try{
r= new BufferedReader(new FileReader(filepath));//组装BufferedReader流,加入缓冲能力
char[] data = new char[256];int len = -1;while ((len = r.read(data)) != -1) {//-1 表示读取到达文件结尾//操作数据
for (int i = 0; i < len; i++) {
System.out.print(data[i]);
}
}
}finally{if (r != null) {
r.close();//关闭流
}
}
}
}
(2)写入文件与读取文件类似
单字节写入文件示例:
public classtest5 {public static void main(String[] args) throwsException {
String filepath= "test.bin";
java.io.OutputStream os= null;try{
os= newFileOutputStream(filepath);
os.write('1');
os.write('2');
os.write('3');
os.write('4');
os.flush();//把缓冲区内的数据刷新到磁盘
}finally{if (os != null) {
os.close();//关闭流
}
}
}
}
字符数组写入文件示例:
public classtest5 {public static void main(String[] args) throwsException {
String filepath= "file.txt";
java.io.Writer w= null;try{
w= new BufferedWriter(new FileWriter(filepath));//组装BufferedWriter流,加入缓冲能力//模拟
char[] data = new char[256];
String f= "0123456789abcdefghijklmnopqrstuvwxyz";
Random rd= newRandom();for (int i = 0; i < data.length; i++) {
data[i]=f.charAt(rd.nextInt(f.length()));
}
w.write(data);
w.flush();//把缓冲区内的数据刷新到磁盘
} finally{if (w != null) {
w.close();//关闭流
}
}
}
}
(3)随机访问文件
如果你需要不按特定的存取顺序,随意读取或者写入文件,可以考虑RandomAccessFile。
void seek(long pos) 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
public classtest5 {public static void main(String[] args) throwsException {
RandomAccessFile file= null;try{
file= new RandomAccessFile("test.bin", "rw");
file.seek(0);
file.writeChar('1');
file.seek(0);
System.out.println(file.readChar());/*** 读取*/
int data = -1;while ((data = file.read()) != -1) {//-1 表示读取到达文件结尾//操作数据
System.out.print((byte)data + " ");
}
}finally{if (file != null) {
file.close();//关闭流
}
}
}
}