IO流框架总结

普通IO(BIO)/ NIO

字节流

字节输入流

--InputStream
	int available() 返回流中可用的字节数
	void close() 
	abstract  int read() 读取一个字节
	int read(byte[] b) 读取一个字节数组
	int read(byte[] b, int off, int len) 读取字节数组的一部分 
	long skip(long n) 跳过多n个字节读取 
		
		//子类
		--FileInputStream
  			FileInputStream(File file) 
			/*通过打开一个到实际文件的连接来创建一个 FileInputStream,
			该文件通过文件系统中的 File 对象 file 指定。*/ 
			FileInputStream(FileDescriptor fdObj) 
			/*通过使用文件描述符 fdObj 创建一个 FileInputStream,
			该文件描述符表示到文件系统中某个实际文件的现有连接。*/ 
			FileInputStream(String name) 
			/*通过打开一个到实际文件的连接来创建一个 FileInputStream,
			该文件通过文件系统中的路径名 name 指定。 */
						          
		-- BufferedInputStream
			//能够提高读写效率

字节输出流

--OutputStream
	void close() 关闭此输出流并释放与此流有关的所有系统资源。 
	void flush() 将数据从内存中刷新到文件系统中
	void write(byte[] b) 写一个字节数组
	void write(byte[] b, int off, int len) 写一个字节数组的一部分
	abstract  void write(int b) 写一个字节
				
		//子类			
		--FileOutputStream
			FileOutputStream(File file) 
			//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 
			FileOutputStream(File file, boolean append) 
			//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 
			FileOutputStream(FileDescriptor fdObj) 
			/*创建一个向指定文件描述符处写入数据的输出文件流,
			该文件描述符表示一个到文件系统中的某个实际文件的现有连接。*/
			FileOutputStream(String name) 
			创建一个向具有指定名称的文件中写入数据的输出文件流。 
			FileOutputStream(String name, boolean append) 
			创建一个向具有指定 name 的文件中写入数据的输出文件流。 
		
		--BufferedOutputStream
			//能够提高读写效率

字符流

字符输入流

Reader
...
转换流: InputStreamReader
1.处理编码
2.将字节流转化成字符流
FileReader是InputStreamReader子类
高效缓冲字符输入流 BufferedReader
readLine() 读取一行

字符输出流

Writer
...
转换流: OutputStreamWriter
1.处理编码
2.将字节流转化成字符流
FileWriter是OutputStreamWriter子类
高效缓冲字符输出流 BufferedWriter
newLine() 写一个换行符

九种方式拷贝文件

文件拷贝的方式和原理:
1.FileInputStream/FileOutputStream一次性读取一个字节
2.FileInputStream/FileOutputStream一次性读取一个字节数组
3.BufferedInputStream/BufferedOutputStream一次性读取一个字节
4.BufferedInputStream/BufferedOutputStream一次性读取一个字节数组
5.FileReader/FileWriter一次性读取一个字符
6.FileReader/FileWriter一次性读取一个字符数组
7.BufferedReader/BufferedWriter一次性读取一个字符
8.BufferedReader/BufferedWriter一次性读取一个字符数组
9.BufferedReader/BufferedWriter一次性读取一行

代码如下:

package com.sxt.homework;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

/**
 * 	使用至少9种方式拷贝文件 
 * 	文件拷贝的方式和原理:
 * 		1.FileInputStream/FileOutputStream一次性读取一个字节
 * 		2.FileInputStream/FileOutputStream一次性读取一个字节数组
 * 		3.BufferedInputStream/BufferedOutputStream一次性读取一个字节
 * 		4.BufferedInputStream/BufferedOutputStream一次性读取一个字节数组
 * 		5.FileReader/FileWriter一次性读取一个字符
 * 		6.FileReader/FileWriter一次性读取一个字符数组
 * 		7.BufferedReader/BufferedWriter一次性读取一个字符
 * 		8.BufferedReader/BufferedWriter一次性读取一个字符数组
 * 		9.BufferedReader/BufferedWriter一次性读取一行
 * @author berger
 *
 */
public class Homework01 {
	public static void main(String[] args) {
		
	}
	
	//1.FileInputStream/FileOutputStream一次性读取一个字节
	public static void copy1(String srcFileName, String descFileName) {
		try (FileInputStream f1 = new FileInputStream(srcFileName);
				FileOutputStream f2 = new FileOutputStream(descFileName)){
			int by = 0;
			while ((by = f1.read()) != -1) {
				f2.write(by);
				f2.flush();
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	//2.FileInputStream/FileOutputStream一次性读取一个字节数组
	public static void copy2(String srcFileName, String descFileName) {
		try (FileInputStream f1 = new FileInputStream(srcFileName);
				FileOutputStream f2 = new FileOutputStream(descFileName)){
			byte [] by = new byte[8192];
			int len = 0;
			while ((len = f1.read(by)) != -1) {
				for (byte b : by) {
					f2.write(b);
					f2.flush();
				}
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	//3.BufferedInputStream/BufferedOutputStream一次性读取一个字节
	public static void copy3(String srcFileName, String descFileName) {
		try (BufferedInputStream f1 = new BufferedInputStream(new FileInputStream(srcFileName));
				BufferedOutputStream f2 = new BufferedOutputStream(new FileOutputStream(descFileName))){
			int by = 0;
			while ((by = f1.read()) != -1) {
				f2.write(by);
				f2.flush();
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	//4.BufferedInputStream/BufferedOutputStream一次性读取一个字节数组
	public static void copy4(String srcFileName, String descFileName) {
		try (BufferedInputStream f1 = new BufferedInputStream(new FileInputStream(srcFileName));
				BufferedOutputStream f2 = new BufferedOutputStream(new FileOutputStream(descFileName))){
			byte [] by = new byte[8192];
			int len = 0;
			while ((len = f1.read(by)) != -1) {
				for (byte b : by) {
					f2.write(b);
					f2.flush();
				}
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	//5.FileReader/FileWriter一次性读取一个字符
	public static void copy5(String srcFileName, String descFileName) {
		try (FileReader f1 = new FileReader(srcFileName);
				FileWriter f2 = new FileWriter(descFileName)){
			int by = 0;
			while ((by = f1.read()) != -1) {
				f2.write(by);
				f2.flush();
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	//6.FileReader/FileWriter一次性读取一个字符数组
	public static void copy6(String srcFileName, String descFileName) {
		try (FileReader f1 = new FileReader(srcFileName);
				FileWriter f2 = new FileWriter(descFileName)){
			char [] by = new char[8192];
			int len = 0;
			while ((len = f1.read(by)) != -1) {
				for (char c : by) {
					f2.write(c);
					f2.flush();
				}
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	//7.BufferedReader/BufferedWriter一次性读取一个字符
	public static void copy7(String srcFileName,String descFileName) {
		try(Reader f1 = new BufferedReader(new FileReader(srcFileName));
				Writer f2 = new BufferedWriter(new FileWriter(descFileName))){
			int by = 0;
			while ((by = f1.read()) != -1) {
				f2.write(by);
				f2.flush();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		} 
	}
	
	//8.BufferedReader/BufferedWriter一次性读取一个字符数组
	public static void copy8(String srcFileName, String descFileName) {
		try (BufferedReader f1 = new BufferedReader(new FileReader(srcFileName));
				BufferedWriter f2 = new BufferedWriter(new FileWriter(descFileName))){
			char [] ch = new char[8192];
			int len = 0;
			while ((len = f1.read(ch)) != -1) {
				for (char c : ch) {
					f2.write(c);
					f2.flush();
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//9.BufferedReader/BufferedWriter一次性读取一行
	public static void copy9(String srcFileName, String descFileName) {
		try (BufferedReader f1 = new BufferedReader(new FileReader(srcFileName));
				BufferedWriter f2 = new BufferedWriter(new FileWriter(descFileName))){
			while ((f1.readLine()) != null) {
				f2.write(f1.readLine());
				f2.newLine();
				f2.flush();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

基本数据类型流

可以读写基本数据类型

数据输入流:DataInputStream
DataInputStream(InputStream in)
数据输出流:DataOutputStream
DataOutputStream(OutputStream out)

特点:

  1. 该流是一个字节流,可以读写字节的同时,还能够读写基本数据类型
  2. 通过数据类型输出流写入到文件中,使用文本文件打开是不能阅读,提高了基本数据类型在文件中保存的安全性
  3. 读的时候必须和写的顺序保持一致,提高了基本数据类型在文件中保存的安全性

PrintWriter / PrintStream

概述:
向文本输出流打印对象的格式化表示形式。此类实现在 PrintStream 中的所有 print 方法。
特点:
只能写数据,不能读取数据。
可以操作任意类型的数据。
如果启动了自动刷新,能够自动刷新。

输入输出流

系统流不需要我们自己创建,直接使用即可
代码演示如下:

public class OtherIODemo03 {
	public static void main(String[] args) throws IOException {
		PrintStream ps = System.out;
		ps.append("hello");		
		System.out.println("HelloWorld");		
		ps.println(new Object());		
		PrintStream ps2 = System.err;
		ps2.println("great");
		
		InputStream in = System.in;
		byte[] bys = new byte[10];
		int len = in.read(bys);
		System.out.println(new String(bys, 0, len));
		
		// java.util.InputMismatchException
		Scanner input = new Scanner(System.in);
		double d = input.nextDouble();
		System.out.println(d);
		
		InputStream in = System.in;
		InputStreamReader isr = new InputStreamReader(in);
		BufferedReader br = new BufferedReader(isr);
		System.out.print("请输入数据:");
		String line = br.readLine();
		double d = Double.parseDouble(line);
		System.out.println("您输入的数据是: " + d);
		
		MyScanner input = new MyScanner(System.in);
		System.out.print("请输入字符串: ");
		String line = input.nextLine();
		System.out.println("数据: " + line);
		
		System.out.print("请输入小数: ");
		double d = input.nextDouble();
		System.out.println("小数: " + d);
	}
}

// 自定义Scanner类
class MyScanner {
	// 通过外界传入输入流
	private InputStream is;
	
	public MyScanner() {}
	
	public MyScanner(InputStream is) {
		this.is = is;
	}
	
	public String nextLine() {
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		try {
			String line = br.readLine();
			return line;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public double nextDouble() throws InputMismatchException {
		String line = this.nextLine();
		try {
			double d = Double.parseDouble(line);
			return d;
		} catch (NumberFormatException e) {
			throw new InputMismatchException("hey! 你要输入小数啊!!!!");
		}
	}
}

RandomAccessFile

概述:此类的实例支持对随机访问文件的读取和写入。
特点:

  1. RandomAccessFile类不属于流,是Object类的子类。
  2. 包含了InputStream和OutputStream的功能。
  3. 能够读写基本类型
  4. 支持对随机访问文件的读取和写入。 getFilePointer/seek
    long getFilePointer()
    long length()
    void seek(long pos)
    void setLength(long newLength)
public class OtherIODemo04 {
	public static void main(String[] args) throws Exception {
//		write();
		read();
	}

	private static void read() throws Exception {
		RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
		System.out.println(raf.length());
		raf.seek(4);
		byte[] bys = new byte[5];
		int len = raf.read(bys);
		System.out.println(new String(bys, 0, len));
//		int i = raf.readInt();
//		System.out.println(i);
		System.out.println(raf.getFilePointer());
		raf.close();
	}

	private static void write() throws Exception {
		RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
		raf.writeInt(100);
		raf.write("中国".getBytes());
		raf.close();
	}
}

序列化流与反序列化流(ObjectOutputStream ObjectInputStream)

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。
可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。
如何实现序列化?
类通过实现 java.io.Serializable 接口以启用其序列化功能。
未实现此接口的类将无法使其任何状态序列化或反序列化,该接口没有任何方法,是一个标机接口。
未实现序列化抛出未序列化异常:NotSerializableException。
序列化数据后,再次修改类文件,读取数据会出问题,如何处理?
使用transient关键字声明不需要序列化的成员变量。

java.io.Not Serializable Exception

java.io.InvalidClassException: com.sxt.otheriodemo.Student;
local class incompatible: 
stream classdesc serialVersionUID = 7512677611218988631, 
local class serialVersionUID = -6596699813872332589

第一次写入的是后 class文件对应的序列化ID是123456 流中的序列化ID是123456
第一次从流中读取学生对象 
		流中的序列化ID是123456 = class文件对应的序列化ID是123456
		
第二次从流中读取学生对象
		local class serialVersionUID = -6596699813872332589
		流中的序列化ID是123456 

Properties

概述:
Properties 类表示了一个持久的属性集;Properties 可保存在流中或从流中加载;属性列表中每个键及其对应值都是一个字符串。
Properties可以当做Map集合类使用
Properties的特殊遍历功能

public Object setProperty(String key,String value)
public String getProperty(String key)
public Set<String> stringPropertyNames()
Properties和IO流结合使用
public void load(Reader reader)
public void store(Writer writer,String comments)

配置文件:

  1. Properties 轻量级,在网络中传输带宽小,本地存储数据量简单,就是键值对结构,理解为一个类似于map的文件
  2. XML 重量级,结构化清晰,可读性强,能够存储复杂结构的数据
发布了38 篇原创文章 · 获赞 8 · 访问量 3338

猜你喜欢

转载自blog.csdn.net/hcwdd/article/details/89854200