JAVA 中的 IO流、字节流、字符流、缓冲流、转换流、序列流、打印流

JAVA 中的 IO流、字节流、字符流、缓冲流、转换流、序列流、打印流

IO 概述

一切文件数据(文本、图片、视频等)在存储时,都是以二进制的形式保存,传输时同样如此。所以字节流可以传输任意数据。 在操作流的时候,无论使用什么样的流对象,底层传输的始终为二进制数据。

流的分类

根据数据的流向分为:输入流输出流

  • 输入流 :硬盘 --> 内存
  • 输出流 :内存 --> 硬盘

根据数据的类型分为:字节流字符流
另外还有:缓冲流转换流序列流打印流

第一章:字节流

1.1 字节输出流(OutputStream)

简述:java.io.OutputStream 抽象类是表示字节输出流的所有类的父类(超类),将指定的字节信息写到目的地。

字节输出流的基本共性功能方法:
public void close()  // 关闭此输出流并释放与此流相关联的任何系统资源。
public void flush() // 刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(byte[] b) // 将b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) // 从指定的字节数组写入 len字节,从偏移量 off开始输 出到此输出流。
public abstract void write(int b) // 将指定的字节输出流。
FileOutputStream

简述: java.io.FileOutputStream 类是文件输出流,用于将数据写出到文件。

public FileOutputStream(File file) // 创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name) // 创建文件输出流以指定的名称写入文件
使用步骤:
  1. 创建FileOutputStream对象,构造方法中传递文件路径
  2. 调用FileOutputStream对象中的方法write,把数据写入到文件中
  3. 释放资源(关闭文件)
练习:
public static void main(String[] args) throws IOException {
     
	FileOutputStream fos1 = new FileOutputStream("E:\\test\\abc.txt");
	FileOutputStream fos2 = new FileOutputStream(new File("E:\\test\\abc.txt"));
	// 写入单个字节
	fos1.write(97);

	// 写入字节数组
	byte[] bytesArray = "你好".getBytes();
	System.out.println(Arrays.toString(bytesArray)); // [-28, -67, -96, -27, -91, -67]
	fos2.write(bytesArray);
	// 释放资源
	fos1.close();
	fos2.close();
}

1.2 字节输入流(InputStream)

简述:java.io.InputStream 抽象类是表示字节输入流的所有类的父类(超类),可以读取字节信息到内存中。

字节输出流的基本共性功能方法:
public void close() // 关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read() // 从输入流读取数据的下一个字节。
public int read(byte[] b) // 从输入流中读取一些字节数,并将它们存储到字节数组 b中
FileIntputStream

简述:java.io.FileInputStream类是文件输入流,从文件中读取字节。

使用步骤:
  1. 创建FileInputStream对象,构造方法中传入要读取的数据源文件
  2. 使用FileInputStream对象中的方法read,读取文件
  3. 释放资源
练习:
# 文件的复制
FileInputStream fis = new FileInputStream("E:\\test\\a\\1.jpg");
FileOutputStream fos = new FileOutputStream("E:\\test\\b\\1.jpg");

int len = 0;
byte[] bytes = new byte[1024]; 
while ((len = fis.read(bytes)) != -1) {
     
	fos.write(bytes, 0, len); 
}
// 释放资源
fos.close();
fis.close();

第二章:字符流

简述:当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,因为一个中文字符占用多个字节存储(GBK占用两个字节,UTF-8占用三个字节)。所以JAVA提供了字符流类,以字符为单位读写数据,专门用于处理文本文件。

1.1 字符输入流(Reader)

简述:java.io.Reader抽象类是字符流最顶层的父类(超类),可以读取字符信息到内存中。

public void close() // 关闭此流并释放与此流相关联的任何系统资源。
public int read() //从输入流读取一个字符。
public int read(char[] cbuf) // 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。
FileReader 构造方法
  • FileReader(File file)
  • FileReader(String fileName)
练习
FileReader fr1 = new FileReader("E:\\test\\a.txt");
FileReader fr2 = new FileReader("E:\\test\\b.txt");
// 读取一个字符
int len = 0;
while ((len = fr1.read()) != -1) {
     
	System.out.println(len);
}
// 读取多个字符
int len =0;
char[] cs = new char[1024]; 
while ((len = fr1.read(cs)) != -1) {
     
	System.out.println("长度" + len);
	System.out.println(new String(cs, 0, len)); 
}
// 释放资源
fr1.close();
fr2.close();

1.2 字符输出流(Writer)

简述:java.io.Writer 字符输出流,是所有字符输出流的父类,是一个抽象类。

FileWriter 构造方法
  • FileWriter(File file)
  • FileWriter(String fileName)
使用步骤
  1. 创建FileWriter对象,构造方法中传入要写入数据的目的地
  2. 使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换成字节的过程)
  3. 使用FileWriter中的flush,把缓冲区中的数据写入到硬盘
  4. 释放资源(会先把内存缓冲区中的数据刷新到硬盘中)
练习
FileWriter fw1 = new FileWriter("E:\\test\\c.txt"); 
FileWriter fw2 = new FileWriter("E:\\test\\c.txt", false); 

// 写入数据
fw1.write(97);
char[] cs = {
      'a', 'b', 'c', 'd', 'e' };
fw1.write(cs); 
fw1.write(cs, 1, 3); 

// 换行: windows:\r\n Linux:/n Unix: /r
for (int i = 0; i < 10; i++) {
     
	fw1.write("HelloWorld" + i + "\r\n"); // 换行写入
}
// 将缓冲区的数据刷新到硬盘
fw1.flush();
// 释放资源
fw1.close();

第三章:缓冲流

简述: 功能更强大的流,能够高效读写的缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化流等等。这些都是在基本的流对象基础之上创建而来的,是对基本流对象的一种增强

1.1 字节缓冲流

继承自父类的共性成员方法:
public void close()
public void flush()
public void write(byte[] b)
public void write(byte[] b, int off, int len)
public abstract void write(int b)

1.11 BufferedOutputStream

构造方法:
  • BufferedOutputStream(OutputStream out)
  • BufferedOutputStream(OutputStream out, int size)
使用步骤:
  1. 创建FileOutputStream对象,构造方法中绑定要输出的目的地
  2. 创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream对象效率
  3. 使用BufferedOutputStream对象中的write方法,把数据写入到内部缓冲区中
  4. 使用BufferedOutputStream对象中的flush方法,把内部缓冲区中的数据刷新到文件中
  5. 释放资源(会先调用flush方法刷新数据)
练习
FileOutputStream fos = new FileOutputStream("E:\\test\\c.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write("把数据写到缓冲区中".getBytes());
bos.flush();
bos.close(); 

1.12 BufferedIntputStream

构造方法:
  • BufferedIntputStream(OutputStream out)
  • BufferedIntputStream(OutputStream out, int size)
使用步骤:
  1. 创建FIleInputStream对象,构造方法中传入读取的数据源
  2. 创建BufferedInputStream对象,构造方法中传入FIleInputStream
  3. 使用BufferedInputStream中的read方法,读取文件
  4. 释放资源
练习
FileInputStream fis = new FileInputStream("E:\\test\\c.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] cs = new byte[1024];
int len = 0;
while ((len = bis.read(cs)) != -1) {
     
	System.out.println(new String(cs, 0, len));
}
bis.close();

1.2 字符缓冲流

1.21 BufferedWriter

构造方法:
  • BufferedWriter(Writer out)
  • BufferedWriter(Writer out, int sz)
特有的成员方法:

void newLine() 写入一个行分隔符。会根据不同的操作系统,获取不同的行分隔符

使用步骤:
  1. 创建BufferedWriter对象,构造方法中传入写入的数据源
  2. 调用BufferedWriter中的write方法,把数据写入到内存缓冲区中
  3. 使用BufferedWriter中的flush方法,把内存缓冲区中的数据,刷新到文件中
  4. 释放资源
练习
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\b.txt"));
for (int i = 0; i < 10; i++) {
     
	bw.write("啦啦啦");
	bw.newLine();
}
bw.flush();
bw.close();

1.22 BufferedReader

构造方法:
  • BufferReader(Reader in)
  • BufferReader(Reader in, int sz)
特有的成员方法:

String readline() 读取一行数据
返回值:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回null

使用步骤:
  1. 创建缓冲字符输入流对象,构造方法中传入字符输入流
  2. 使用缓冲字符输入流对象中的read/readline读取文本
  3. 释放资源
练习
BufferedReader br = new BufferedReader(new FileReader("E:\\test\\b.txt"));
String line; // 创建读取的文本行,结尾返回null
while ((line = br.readLine()) != null) {
     
	System.out.println(line);
}
br.close();
字节流 VS 缓冲流
public static void main(String[] args) throws IOException {
     
	long currentTimeMillis = System.currentTimeMillis();
	// FileOutputStream 
	FileInputStream fis1 = new FileInputStream("E:\\test\\a\\a.jpg");
	FileOutputStream fos1 = new FileOutputStream("E:\\test\\b\\a.jpg");
	byte[] bytes = new byte[1024];
	int len = 0; // 读取到的有效字节个数
	
	while ((len = fis1.read(bytes)) != -1) {
     
		fos1.write(bytes, 0, len);
	}

	fos1.close();
	fis1.close();

	long doneTimeMillis = System.currentTimeMillis();
	System.out.println("File 复制文件使用了:" + (doneTimeMillis - currentTimeMillis) + "毫秒");

	// BufferedOutputStream
	long currentTimeMillis2 = System.currentTimeMillis();
	BufferedInputStream bis1 = new BufferedInputStream(new FileInputStream("E:\\test\\a\\b.jpg"));
	BufferedOutputStream bos1 = new BufferedOutputStream(new FileOutputStream("E:\\test\\b\\b.jpg"));
	byte[] bytes2 = new byte[1024];
	int len1 = 0;
	while ((len1 = bis1.read(bytes2)) != -1) {
     
		bos1.write(bytes2, 0, len1);
	}

	bos1.close();
	bis1.close();

	long doneTimeMillis2 = System.currentTimeMillis();
	System.out.println("Buffered 复制文件使用了:" + (doneTimeMillis2 - currentTimeMillis2) + "毫秒");
}
# 输出
File 复制文件使用了:38毫秒
Buffered 复制文件使用了:8毫秒

第四章:转换流

简述:在文件的读取和写入中如果编码不一致有可能导致乱码的问题。转换流中可以指定编码。

1.1 OutputStreamWriter

构造方法:
  • OutputStreamWriter(OutputStream out) 创建使用默认字符编码(UTF-8 )的OutputStreamWriter对象
  • OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的OutputStreamWriter对象。
使用步骤:
  1. 创建OutputStreamWriter对象,构造方法中传入字节输出流和指定的编码
  2. 使用OutputStreamWriter对象中的write方法,把字符转换成字节存储到缓冲区中
  3. 使用OutputStreamWriter中的flush方法,把缓冲区中的字节刷新到文件中
  4. 释放资源
练习
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\test\\utf-8.txt"), "UTF-8");
osw.write("你好");
osw.flush();
osw.close();

1.2 InputStreamReader

是字节流通向字符流的桥梁,它使用指定的charset读取字节将其解码为字符

构造方法:
  • InputStreamReader(InputStream in)
  • InputStreamReader(InputStream in, String charsetName)
使用步骤:
  1. 创建InputStreamReader对象
  2. 调用read方法
  3. 释放资源
练习
InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\test\\utf-8.txt"), "UTF-8");
String line;
int len=0;
while ((len = isr.read()) != -1) {
     
	System.out.print((char) len);
}
isr.close();
PS:编码换成“GBK”则会乱码

第五章:序列流

1.1 ObjectOutputStream

把对象以流的方式写入到文件中

构造方法:
  • ObjectOutputStream(OutputStream out)
特有的成员方法:
  • void writeObject(Object obj) 将指定对象写入ObjectOutputStream
使用步骤:
  1. 创建ObjectOutputStream对象,传入字节输出流
  2. 使用ObjectOutputStream中的writeObject方法,把对象写入文件中
  3. 释放资源
# Person类
public class Person implements Serializable {
     
	private String name;
	private int age;
	public Person() {
     
		super();
	}
	public Person(String name, int age) {
     
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
     
		return name;
	}
	public void setName(String name) {
     
		this.name = name;
	}
	public int getAge() {
     
		return age;
	}
	public void setAge(int age) {
     
		this.age = age;
	}
	@Override
	public String toString() {
     
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

# main
public static void main(String[] args) throws IOException {
     
	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\test\\obj.txt"));
	oos.writeObject(new Person("赵丽颖", 18));
	oos.close();
}
注意:Person类需要implements Serializable 类才能序列和反序列化

1.2 ObjectInputStream

简述:把文件中保存的对象以流的方式读取出来

构造方法:
  • ObjectInputStream(InputStream in)
特有的成员方法:
  • Object readObject()
使用步骤:
  1. 创建ObjectInputStream对象,传入字节输入流
  2. 使用ObjectInputStream中的readObject方法读取保存对象的文件
  3. 释放资源
  4. 使用读取出来的对象
练习
// 读取上个练习存入的对象(重写了toString方法)
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\test\\obj.txt"));
Object readObject = ois.readObject();
ois.close();
System.out.println(readObject);

// 将读取出来的对象强转成Person类型,然后进行使用
Person p = (Person) readObject;
System.out.println(p.getName() + ", " + p.getAge());

# 输出
Person [name=赵丽颖, age=18]
赵丽颖, 18

第六章:打印流

简述:平时我们调用 print 和 println 方法完成的,这两个方法都来自于 java.io.PrintStream 该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。

1.1 PrintStream

构造方法:
PrintStream(File file) 		// 输出的目的地是一个文件
PrintStream(OutputStream out)	// 输出的目的地是一个字节输出流
PrintStream(String fileName)	// 输出的目的地是一个文件路径
练习
public static void main(String[] args) throws FileNotFoundException {
     
	PrintStream ps = new PrintStream("E:\\test\\p.txt");
	ps.write(97);// 使用继承的write方法写入,结果:a

	ps.println(97); // 97
	ps.println("HelloWorld");
	ps.println(8.8);
	ps.println(true);
	// 释放资源
	ps.close();
}
改变打印流向:
PrintStream p2 = new PrintStream("E:\\test\\p.txt");
System.out.println("在控制台输出");
System.setOut(p2); // 把输出语句的目的地改变为打印流的目的地
System.out.println("在打印流的目的地输出");
// 释放资源
p2.close();

总结

JAVA 中的 IO流、字节流、字符流、缓冲流、转换流、序列流、打印流_第1张图片

你可能感兴趣的:(JAVA,java,流处理)