Java IO操作(原理详细)


前言

Java中把输入(Input)/输出(Output) 称为I/O ,也称为流(Stream) ,相关的类型被封装的java.io包中

一、什么是流?

从起点到终点有序的数据序列

二、流的分类:

2.1 按照方向划分:

输入流: 我们只会从流中读取数据,也就是只读的
输出流: 我们只会向流中写入数据,也就是只写的;

按照处理的数据分:
字节流: 以字节为单位,也就是在读取/写入的时候,以字节为单位
字符流: 以字符为单位; 也就是是在读取/写入的时候,以字符为单位

按照处理的功能分:
低级流: 直接从数据的源头读取数据,或直接把数据写到目标,就称为节点流
高级流: 对一个已经存在的流的连接和封装,称为高级流, 也称为处理流

2.2读入数据

我们在讲解IO的时候,会以字节流,字符流为纲领
InputStream 字节输入流 ,是只读的,所以肯定会有read()的方法
OutputStream 字节输出流,是只写的,所以肯定会有write()的方法

2.3.使用流的套路:

我们不会直接使用低级流在操作数据,我们都会在低级流的上面接一个高级流
在初始化的时候,首先初始化低级流,然后才初始化高级流
如何区分低级流,高级流呢?
创建流对象的时候,如果构造方法的参数是一个源文件或目标文件,这个流肯定是低级流
创建流对象的时候,如果构造方法的参数是另外一个流,这个流肯定就是高级流

使用低级字符流FileRead读取文件的内容,读取处理的内容是char[ ],需要我们自己把char[]转为String .所以我在低级流上面接一个BufferedReader,可以直接读取出String

我们需要向文件中写入String数据,可以使用如下的搭配,方便的将String写到文件中

2.4.对象序列化:

我们需要把一个对象写到文件中,应该使用字节流,需要使用FileOutputStream.但是FileOutputStream不能直接写对象到文件,给FileOutputStream接上一个高级流, 这个高级流应该有什么功能? 高级流应该具有直接写对象到流中的方法!
写对象到文件中
对象是一块内存空间,这块内存空间是无法被写到文件中的,就像现实中我们不能把一个大活人写到文件中
写对象到文件中 ,其实质是将对象的信息写到文件中,这种形式称为序列化
对象的完整类名信息,对象的实例属性信息会被写入到文件中;
而对象中的静态属性,局部变量,方法等其他信息,是不会被写到文件中的

从文件中读取对象,称为反序列化
所谓的反序列化的实质:从文件中读取出来的是对象的信息,然后根据这些信息重新创建了一个新的对象

在序列化的类中,要声明一个private static final long serialVersionUID
告诉JVM,我们这个类无论如何变化,该类的版本号都是固定的
在序列化一个对象的时候,要求该类中所有的实例属性的类型都要实现Serializable
对于对象中根本就不能序列化的属性,使用transient修饰符,就不要写该属性了,并且防止程序出现异常

2.5.对象序列化机制(object serialization)

是Java语言内建的一种对象持久化方式,通过对象序列化,可以把对象保存为字节数组,这些字节数组可以保存在磁盘上,或通过网络传输。在有需要的时候将这个字节数组通过反序列化的方式再转换成对象。对象序列化可以很容易的在JVM中的活动对象和字节数组(流)之间进行转换。

2.6.字节流的读与写代码演示

package com.Oracle.demo.v1;

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

//字节流的读与写

public class TestByteReadAndWrite {

	// 每次读取一个字节
	public static void readFile1() {

		try (FileInputStream fin = new FileInputStream("D:\\NBA.txt");) {

			int i = 0;
			// 读取一个字节,当做int, 赋值给i; 判断i是否等于-1,也就是是否读取到文件末尾
			while ((i = fin.read()) != -1) {			
				// 把读取到字节转换为char进行输出
				System.out.print((char) i);//没有换行符ln
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e1) {

			e1.printStackTrace();
		}
	}

	// 每次读取多个字节
	public static void readFile2() {

		try (FileInputStream fin = new FileInputStream("D:\\NBA.txt");) {

			int i = 0;
			byte[] b = new byte[150];
			// 把读取的字节放到字节数组b中,返回的是读取到的字节的个数
			// 如果遇到文件末尾,返回的是-1
			while ((i = fin.read(b)) != -1) {
				
				// 把字节数组中的数据转换为String
				String str = new String(b,0,i);//0~i为文件长度,保证读取内容不重复
				System.out.print(str);//没有换行符ln
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e1) {

			e1.printStackTrace();
		}
	}
	
	//字节流写
	public static void writeFile() {

		// 我们使用FileOutputStream写文件的时候,当目标文件不存在,JVM会创建这个文件
		// 如果目标文件已经存在,则会将数据写到这个已经存在的文件中
		try(FileOutputStream fout = new FileOutputStream("D:\\zbc.txt",true);) {
			
			String str = "// 调用map.keySet()方法,取出Map集合中所有的key,返回的是一个Set \n";
			byte[] b = str.getBytes();// 把字符串转换为byte[]
			for(int i=0;i<1000;i++) {
				fout.write(b);
			}
			System.out.println("文件写入成功");
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	public static void main(String[] args) {
		//readFile1();
		//readFile2();
		
		//writeFile();
		
	}

}



7.字符流的读与写代码演示
package com.Oracle.demo.v1;

import java.io.*;

//使用低级字符流读取/写入文件

public class TestCharReadAndWrite {

	// 一个字符读
	public static void readFile1() {
		try (FileReader fr = new FileReader("E:\\BJ_oracle\\20201124\\课堂练习(1).txt")) {

			int i = 0;
			while ((i = fr.read()) != -1) {
				System.out.print((char) i);// 以字符形式读取
			}
			System.out.println("读取完毕");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 字符数组读
	public static void readFile2() {
		try (FileReader fr = new FileReader("E:\\BJ_oracle\\20201124\\课堂练习(1).txt")) {

			int i = 0;
			char[] b = new char[100];
			while ((i = fr.read(b)) != -1) {
				String str = new String(b, 0, i);
				System.out.print(str);
			}
			System.out.println("读取完毕");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 使用高级流BufferReader,每次读取一行String
	public static void readFile3() {
		try (FileReader fr = new FileReader("E:\\BJ_oracle\\20201124\\课堂练习(1).txt");
				BufferedReader br = new BufferedReader(fr);) {

			String str = null;
			while ((str = br.readLine()) != null) {
				System.out.println(str);
			}
			System.out.println("读取完毕");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void writeFile() {

		// 在写文件的时候,如果没有指定文件的路径信息,该文件会被写到Eclipse当前的项目中
		try (FileWriter fw = new FileWriter("e:\\abc.txt", true); PrintWriter pw = new PrintWriter(fw);) {

			for (int i = 0; i < 100; i++) {
				String str = i + ".我们需要向文件中写入String数据,可以使用如下的搭配,方便的将String写到文件中";
				pw.println(str);
			}
			System.out.println("写入完毕");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {

		// readFile1();
		// readFile2();
		// readFile3();

		writeFile();
	}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值