Java IO流


阳光少年     2020-08-28     837

Java IO流

目录

什么是IO流?

  • I: Input

  • O: Output

  • 通过IO流可以完成硬盘的读写操作

IO流的分类

  • 按照流的方向进行分类

    • 读入内存: 输入(Input)
    • 写到硬盘: 输出(Output)
  • 按读取方式进行分类

    • 字节流: 按字节方式,一次读取1个字节(8个二进制位),这种流是万能的,能读文本,视频,音乐等
    • 字符流: 按照字符方式读取数据,一次读取1个字符,这种流只能读取文本文件

综上所述,流分为:

  • 输入流、输出流、字节流、字符流

Java的四大流

  • InputStream 字节输入流

  • OutputStream 字节输出流

  • FileReader 字符输入流

  • FileWriter 字符输出流

  • 所有的流都是可关闭的,都实现了Closeable接口,都有close()方法

  • 所有的输出流都是刷新的,都实现了Flushable接口,都有flush()方法

FileInputStream

package Demo1;

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

public class Test02 {

	public static void main(String[] args) {
		
		FileInputStream fis = null;
		
		StringBuffer sb = new StringBuffer(16);
		
		try {
			//一次读取4个字节
			byte[] bytes = new byte[5];
			//创建输入字节流
			fis = new FileInputStream("name");

			//获取未读取的字节数量
			System.out.println("未读取的字节数: " + fis.available());
			
			//可以这样读取,不适合大数据量
			/*
			 * byte[] readAll = new byte[fis.available()]; fis.read(readAll);
			 * System.out.println("一次性读取: " + new String(readAll));
			 */
			
			//返回的是读入的字节个数,如果没有读到返回-1
			int i = 0;
			while((i = fis.read(bytes)) != -1) {
				//将有效部分转换为string
				sb.append(new String(bytes,0,i));
			}
			
			System.out.println(sb);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
	
}

FileOutputStream

package Demo1;

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

public class FileoutputStreamTest {

	public static void main(String[] args) {
		
		FileOutputStream fos = null;
		FileOutputStream fos1 = null;
		
		
		try {
			//以覆盖的方式将byte数组写入
			fos = new FileOutputStream("name");
			//byte数组
			byte[] file = {97,98,99,100,101};
			//将byte数组写入
			fos.write(file);
			//刷新
			fos.flush();
			
			//以追加的方式写入
			fos1 = new FileOutputStream("name1",true);
			//String
			String country = "我是一个中国人,我骄傲 !";
			//将String转换为byte数组
			byte[] stringvalue = country.getBytes();
			//将byte数组写入
			fos1.write(stringvalue);
			//刷新
			fos1.flush();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
	}
	
}

字节流copy文件

package Demo1;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopy {

	public static void main(String[] args) {
		

		copy();
		
		
	}
	
	
	public static void copy() {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		
		try {
			//创建字节输入流
			fis = new FileInputStream("C:\\Users\\28229\\Pictures\\ip.JPG");
			fos = new FileOutputStream("C:\\Users\\28229\\Desktop\\a.jpg",true);
			
			//读入字节输入流
			int count = 0;
			
			//byte数组
			byte[] bytes = new byte[10];
			
			//读取
			while((count = fis.read(bytes)) != -1) {
				//写入
				fos.write(bytes, 0, count);
				fos.flush();
			}
			
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	
}

字符流copy文件

package DemoFileRW;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyRW {

	public static void main(String[] args) {
		
		FileReader fr = null;
		FileWriter fw = null;
		
		try {
			//创建字符输入流
			fr = new FileReader("b.txt");
			fw = new FileWriter("C:\\Users\\28229\\Desktop\\file.txt");
			
			//读入文件
			char[] chars = new char[10];
			int count = 0;
			while((count = fr.read(chars)) != -1) {
				//写
				fw.write(chars,0,count);
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if (fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			if (fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
		}
		
	}
	
	
}


字符缓冲流

package Buffer;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderTest {

	public static void main(String[] args) throws IOException {
		
		//创建字符缓冲流
		BufferedReader br = new BufferedReader(new FileReader("01.java"));
		
		//读取一行
		String line = null;
		while((line = br.readLine()) != null) {
			//读取的数据是不带换行符的
			System.out.println(line);
		}
		
		if (br != null) {
			br.close();
		}
		
	}
	
}


转换流


package Buffer;

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

public class Convert {

	public static void main(String[] args) throws IOException {
		
		
		/*
		 * //字节输入流 FileInputStream fis = new FileInputStream("01.java");
		 * 
		 * //将字节输入流转换为字符输入流 InputStreamReader isr = new InputStreamReader(fis);
		 * 
		 * //字符缓冲流 BufferedReader br = new BufferedReader(isr);
		 */
		
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("01.java")));
		
		String line = null;
		while((line = br.readLine()) != null) {
			System.out.println(line);
		}
	
		//关闭最外层
		br.close();
		
	}
	
}


标准输出流


package PrintStreamDemo;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Logger {

	public static void log(String message) {
		
		
		try {
			
			//创建标准输出流,指向log.txt
			PrintStream ps = new PrintStream(new FileOutputStream("log.txt",true));
			
			//改变输出方向
			System.setOut(ps);
			
			//输出
			ps.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()) + message);
			
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}


package PrintStreamDemo;


public class PrintStreamTest {

	public static void main(String[] args) {
		
		Logger.log("登录失败!");
		Logger.log("调用xxx方法");
		
	}
	
}


序列化与反序列化

  • 当一个类去实现Serializable接口,jvm会自动生成一个序列号,序列号是用来区分类的
  • Java是如何区分类的?
    • 通过类名,如果类名相同,再通过序列号进行区分
  • 自动生成的序列号有什么缺点?
    • 后续无法更改代码,因为重新编译会生成新的序列号,此时jvm会认为这是新的一个类
    • 所以建议实现Serializable接口的类,手动初始化序列号
    • 如果之前序列化了一个类,没有手动初始化序列号,那麽后续改代码后会生成新的序列号,导致无法重写反序列化
package Serialize;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

public class Test {

	/*
	 * 参与序列化的类,必须实现Serializable标识接口
	 */
	
	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
		//创建student对象
		Student s = new Student("张三",18);		
		
		Student s1 = new Student("lisi",20);
		
		List<Student> students = new ArrayList<>();
		
		students.add(s);
		students.add(s1);
		
		
		//序列化
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students"));
		
		//序列化
		oos.writeObject(students);
		
		oos.flush();
		
		oos.close();
		
		
		//反序列化
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("students"));
		
		Object objs = ois.readObject();
		
		
		if (objs instanceof List) {
			objs = (List<Student>)objs;
			
			/*
			 * Student [name=张三, age=18]
				Student [name=lisi, age=20]
			 */
			for (Student student : students) {
				System.out.println(student);
			}
		}
		
		ois.close();
		
	}
	
}


package Serialize;

import java.io.Serializable;

public class Student implements Serializable{

	//手动初始化序列号
    private static final long serialVersionUID = -546546465465465465L;

	//transient: 标识修饰的属性不参与序列化操作
	private transient String name;
	private int age;
	
	public Student() {}
	
	public Student(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 "Student [name=" + name + ", age=" + age + "]";
	}

}