10.19-IO流

流根据功能可以划分为输入流与输出流

输入流:用于读取数据

输出流:用于写出数据

输入输出流的参照对象是基于我们的程序而言的

流的划分

基于处理单位

  • 字节流:以字节为单位读写数据

  • 字符流:以字符为单位读写数据

基于级别

  • 高级流:不能独立的存在,必须基于另外一个流工作

  • 低级流:数据有明确的来源或去向

字节输入输出流的父类

  • InputStream 字节输入流的父类

  • OutputStream 字节输出流的父类

FIS/FOS 用于读写文件的流

FileInputStream:文件字节输入流

例子-FileInputStream

package day10_19;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * 文件字节输入流
 */
public class FileInputStreamDemo01 {
	public static void main(String[] args) throws Exception {
		/*
		 * FileInputStream(File file)
		 * FileInputStream(String fileName)
		 * 基于给定的文件名创建用于读写文件的输入流
		 */
		FileInputStream fis = 
				new FileInputStream("fos.dat");
		/*
		 * int read()
		 * 读取一个字节,并以int值的形式返回
		 * 低八位有效,若返回-1,则EOF
		 */
		System.out.println((char)fis.read());
		/*
		 *  int read(byte[] b)
		 *  一次性尝试最多读取给定字节数组长度的字节,并将读取到的结果存入到给定的字节数组中
		 *  返回值为实际读取到的字节量
		 */
		byte[] array=new byte[100];
		int len = fis.read(array);
		 System.out.println(len);
		 //反序列化(解码)
//		 String str = new String(array, "UTF-8");
//		 System.out.println(str);
		 //String(byte[] b,int start,int len,String CS)
		 String str = new String(array, 0, len, "UTF-8");
		 System.out.println(str);
		 fis.close();
 	}
}

FileOutputStream:文件字节输出流

例子-FileOutputStream

package day10_19;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

/**
 * 文件字节输出流
 */
public class FileOutputStreamDemo01 {
	public static void main(String[] args) throws Exception {
		/*
		 * FileOutputStream(File file)
		 * FileOutputStream(String fileName)
		 * 基于给定的文件名创建用于写文件的输出流
		 */
		FileOutputStream fos = new FileOutputStream("fos.dat");
		/*
		 * void write(int d)
		 * 写出一个字节,写出给定int值的低八位
		 */
		fos.write('A');
		/*
		 * void write(byte[] b)		 
		 * 将给定字节数组中所有的字节一次性全部写出 
		 */
		String str="你好啊";
		byte[] data=str.getBytes("UTF-8");
		fos.write(data);
		/*
		 * void write(byte[] b,int start,int len)
		 * 将给定的字节数组中从start处开始,连续将len个字节输出
		 */
		//关闭流
		fos.close();
	}
}

例子-注意事项

package day10_19;

import java.io.FileOutputStream;

/**
 * 文件字节输出流
 */
public class FileOutputStreamDemo02{
	public static void main(String[] args) throws Exception {
//		FileOutputStream fos = 
//				new FileOutputStream("fos.dat");
//		//当重新写入内容时,该文件原先内容会被废弃
//		fos.write('B');
//		fos.close();
		/*
		 * FileOutputStream(File file,boolean append)
		 * FileOutputStream(String fileName,boolean append)
		 * 基于给定的文件名创建用于写文件的输出流
		 * 在当前文件上追加写操作
		 */
		FileOutputStream fos = 
				new FileOutputStream("fos.dat", true);
		fos.write('C');
		fos.close();
		
	}
}

BIS/BOS 高级流

BufferedInputStream : 缓存字节输入流

BufferedOutputSteam :缓存字节输出流

高级流:会带一些额外的功能

例子-BufferedOutputSteam

package day10_19;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

public class BufferedOutputSteamDemo01 {
	/**
	 * 高级流不能独立工作,必须基于另外一个流
	 * 缓存流的功能:
	 * 内部维护了一个缓存区,用于减少读写次数,提高读写效率
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		FileOutputStream fos = 
				new FileOutputStream("bos.txt");
		BufferedOutputStream bos = //自带一个8KB缓存
				new BufferedOutputStream(fos);
		//序列化
		String str = "大家好";
		byte[] data = str.getBytes("UTF-8");
		bos.write(data);
		/*
		 * 当我们通过缓存字节输出流写出数据之后,
		 * 如果没有关闭流,数据仍会保存在缓存中,只有在流关闭/刷新后数据才会写入
		 * 在关闭流的时候,我们只需要关闭最外层的高级流即可,
		 * 因为高级流关闭自身之前要先将其处理流关闭后才能关闭自身。
		 */
//		bos.close();
		bos.flush();//将缓存区数据刷新到文件中
		
	}
}

DIS/DOS 高级流

DataInputStream:可以方便读取基本类型的数据

DataOutputStream:可以方便写出基本类型数据

例子-DataOutputStream

package day10_19;

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class DataInputStreamDemo {
	public static void main(String[] args) throws Exception {
		/**
		 * DOS
		 * 该高级流带来的额外功能是方便我们写出基本类型
		 */
		FileOutputStream fos = 
				new FileOutputStream("dos.dat");
		DataOutputStream dos =
				new DataOutputStream(fos);
		dos.writeInt(123);//4
		dos.writeLong(123L);//8
		dos.writeDouble(12.34);//8
		dos.writeUTF("你好");//6+2
		dos.close();
	}
}

例子-DataInputStream

package day10_19;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class DataInputStreamDemo {
	/**
	 * DIS:方便我们读取基本类型的数据
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		FileInputStream fis = 
				new FileInputStream("dos.dat");
		DataInputStream dis = new DataInputStream(fis);
		System.out.println(dis.readInt());
		System.out.println(dis.readLong());
		System.out.println(dis.readDouble());
		System.out.println(dis.readUTF());
		dis.close();
	}
}

例子-高级流叠加使用

package day10_19;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;

/**
 * 高级流的功能可以叠加使用
 * 我们既要可以方便的写出基础类型的数据,又要写的效率高
 * 那么我们可以联合DOS和BOS一起
 *
 */
public class FilterOutputStreamDemo {
	public static void main(String[] args) throws Exception{
		FileOutputStream fos = 
				new FileOutputStream("date.dat");
		BufferedOutputStream bos = 
				new BufferedOutputStream(fos);
		DataOutputStream dos = 
				new DataOutputStream(bos);
		dos.writeInt(12345);
		dos.close();
	}
}

字符流

Reader:所有字符输入流的父类

Writer:所有字符输出流的父类

字符流的处理单位为字符,一次处理一个字符,字符流的底层本质上还是使用的读写字节

ISR/OSW

例子-字符输出

package day10_19;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class OutputStreamWriteDemo01 {
	/**
	 * 字符输出流
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		FileOutputStream fos = 
				new FileOutputStream("osw.txt");
		OutputStreamWriter osw = 
				new OutputStreamWriter(fos);
		/*
		 * void write(int d)
		 * 写出一个字符,写出给定int值的"低16位"
		 * 
		 * void write(char[] c)
		 * 将给定字符数组中的所有字符一次性全部写出
		 * 
		 * void write(char[] c,int start,int len)
		 * 将给定字符数组中从start处开始连续将len个字符写出
		 */
		/*
		 * 默认情况下,write()方法会将当前字符串按照系统默认的字符集转换为字节后写出
		 */
		osw.write("大家好");
		osw.close();
	}
}

例子-字符输入

package day10_19;

import java.io.FileInputStream;
import java.io.InputStreamReader;

public class InputStreamReaderDemo01 {
	/**
	 * 字符输入流
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		FileInputStream fis = 
				new FileInputStream("osw.txt");
		InputStreamReader isr =
				new InputStreamReader(fis);
		/*
		 * int read()
		 * 读取一个字符,并以int值的形式返回
		 * 该int值"低16位"有效
		 * 
		 * int read(char[])
		 * 一次性尝试读取给定字符数组长度的字符,并将读取到的结果存入给定的字符数组中,
		 * 返回值是实际读取到的字符量
		 */
		int c = -1;
		while((c=isr.read())!=-1) {
			System.out.print((char)c);
		}
		isr.close();
	}
}

例子-给定字符集输出

package day10_19;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class OutputStreamWriterDemo02 {
	/**
	 * 按照给定的字符集来写出字符
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		FileOutputStream fos =
				new FileOutputStream("osw2.txt",true);
		/*
		 * OutputStreamWriter(OutputStream out,String )
		 * 使用给定字符集将字符写出
		 */
		OutputStreamWriter osw =
				new OutputStreamWriter(fos, "UTF-8");
		osw.write("大家好");
		osw.close();
	}
}

例子-给定字符集输入

package day10_19;

import java.io.FileInputStream;
import java.io.InputStreamReader;

public class InputStreamReaderDemo02 {
/**
 * 按照指定的字符集读取字符
 */
	
	public static void main(String[] args) throws Exception{
		FileInputStream fis = 
				new FileInputStream("osw2.txt");
		InputStreamReader isr =
				new InputStreamReader(fis,"UTF-8");
		int c = -1;
		while((c=isr.read())!=-1){
			System.out.println((char)c);
		}
		isr.close();
	}
}

BR/BW

可以按行读取字符串

  • BufferedReader 缓存字符输入流

  • BufferedWriter 缓存字符输出流

例子-缓存字符输出

package day10_19;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class BufferedWriterDemo {
	/**
	 * 缓存字符输出流
	 */
	public static void main(String[] args) throws Exception {
		FileOutputStream fos =
				new FileOutputStream("bw.txt", true);
		OutputStreamWriter osw = 
				new OutputStreamWriter(fos, "UTF-8");
		
		/*
		 * BufferedWriter(Writer out)
		 * 将给定的字符输出流转换为缓存字符输出流
		 */
		BufferedWriter bw = 
				new BufferedWriter(osw);
		bw.write("你好");
		bw.close();
	}
}

例子-缓存字符输入

package day10_19;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class BufferedReaderDemo {
/*
 * 缓存字符输入流
 */
	public static void main(String[] args) throws Exception{
		FileInputStream fis = 
				new FileInputStream("bw.txt");
		InputStreamReader isr=
				new InputStreamReader(fis, "UTF-8");
		BufferedReader  br =
				new BufferedReader(isr);
		/*
		 * String readLine()
		 * 一次读取一行字符串
		 * 连续读取若干个字符,直到读取到换行符为止
		 * 返回的字符串中不包含换行符
		 */
		String str = br.readLine();
		System.out.println(str);
		//若readLine()读取到null,则说明EOF
		str = br.readLine();
		System.out.println(str);
		br.close();
		
	}
}

PrintWriter

带自动行刷新的缓存字符输出流

构造器

  • PrintWriter(File file)

  • PrintWriter(String fileName)

  • PrintWriter(OutputStream out)

  • PrintWriter(Writer out)

例子-普通有参构造器

package day10_20;

import java.io.PrintWriter;

public class PrintWriterDemo01 {
	public static void main(String[] args) throws Exception {
		/*
		 * PrintWriter(File file)
		 * PrintWriter(String fileName)
		 * 写文件时,还可以指定字符集
		 * PrintWriter(File file,String csn)
		 * PrintWriter(String fileName,String csn)
		 */
		PrintWriter pw = 
				new PrintWriter("pw.txt","UTF-8");
		pw.write("大家好");
		pw.close();
		
	}
}

例子-自动缓存刷新

package day10_20;

import java.io.FileOutputStream;
import java.io.PrintWriter;

public class PrintWriterDemo02 {
	public static void main(String[] args) throws Exception{
		/*
		 * PrintWriter(OutputStream out)
		 */
		FileOutputStream fos = 
				new FileOutputStream("pw2.txt");
//		PrintWriter pw =
//				new PrintWriter(fos);
//		pw.write("大家好");
//		pw.flush();
		/*
		 * PrintWriter(OutputStream out,boolean autoFlush)
		 * 创建一个带自动行刷新的缓存字符流
		 * 如果想要自动调用flush()方法,则需将write()更换成println()方法
		 */
		PrintWriter pw =
				new PrintWriter(fos, true);
		pw.println("大家好");
		
	}
}

例子-叠加流

package day10_20;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class PrintWriterDemo03 {
	public static void main(String[] args) throws Exception{
		/*
		 * PrintWriter(Writer out)
		 */
		FileOutputStream fos = 
				new FileOutputStream("pw3.txt", true);
		OutputStreamWriter osw = 
				new OutputStreamWriter(fos, "UTF-8");
		PrintWriter pw =
				new PrintWriter(osw, true);
		pw.println("我爱Java!");
		pw.close();
	}
}

对象的序列化/反序列化流

  • ObjectInputStream 对象的反序列化流

  • ObjectOutputStream 对象的序列化流

通常我们序列化对象的目的是用于保存对象和传输对象

例子-序列化与反序列化

首先创建Person类

package day10_20;

public class Person {
	//transient关键字:该关键字修饰的属性在序列化时值会被忽略
	private String name;
	private int age;
	private char sex;
	public Person() {
		
	}
	public Person(String name, int age, char sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	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;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + sex;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (sex != other.sex)
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}
	
}

再创建测试类

package day10_20;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class PersonDemo01 {
	public static void main(String[] args) throws Exception{
		Person p = new Person("张三",23,'男');
		//对象的序列化过程
		FileOutputStream fos =
				new FileOutputStream("person.obj");//OBJ是对象文件
		DataOutputStream dos =
				new DataOutputStream(fos);
		dos.writeUTF(p.getName());
		dos.writeInt(p.getAge());
		dos.writeChar(p.getSex());
		dos.close();
		//对象的反序列化过程
		FileInputStream fis = 
				new FileInputStream("person.obj");
		DataInputStream dis =
				new DataInputStream(fis);
		String name = dis.readUTF();
		int age = dis.readInt();
		char sex = dis.readChar();
		Person p1 = new Person(name,age,sex);
		System.out.println(p1);
	}
}

测试类2

package day04;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class PersonDemo02 {
	public static void main(String[] args) throws Exception{
		Person p = new Person("蔡徐坤",25,'男');
		//使用OOS序列化对象
		FileOutputStream fos = 
				new FileOutputStream("person2.obj");
		ObjectOutputStream oos = 
				new ObjectOutputStream(fos);
		oos.writeObject(p);
		oos.close();
		//使用OIS反序列化对象
		FileInputStream fis = 
			new FileInputStream("person2.obj");
		ObjectInputStream ois = 
			new ObjectInputStream(fis);
		Person person = (Person) ois.readObject();
		System.out.println(person);
	}
}

最后更新于