IO流,字节流,字符流,序列流,内存流,对象流,打印流,随机访问流,Properties类

流(Stream)就是计算机中数据的流动

IO流是单词Input Output Stream的缩写

Java提供了单独的一个包java.io来处理输入输出流

java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能

流的分类

  • 从流的流动方向来看,可以将IO流分为输入流和输出流

  • 从流的数据处理单位来看,可以将IO流分为字节流和字符流

  • 从流的功能来看,还可以将IO流分为节点流和过滤流

流中保存的实际上全都是字节文件

数据进入到CPU叫输入流,从CPU出来叫输出流

数据进入CPU的操作叫读(read),从CPU出来叫写(write)

字节流

  • InputStream:字节输入流基类

  • OutputStream:字节输出流基类

字符流

  • Reader:字符输入流基类

  • Writer:字符输出流基类

简单操作输入输出流,目的是在"E:\\Demo2\\"目录下把a.txt的内容复制到b.txt

FileInputStream fis = new FileInputStream("E:\\Demo2\\a.txt");
FileOutputStream fos = new FileOutputStream("E:\\Demo2\\b.txt");
int len = 0;
byte[] b = new byte[2];
while((len = fis.read(b))!=-1) {
    fos.write(b,0,len);
}
fos.close();
fis.close();

 

FileInputStream

FileOutputStream

FileOutStream在创建对象的时候如果没有这个文件它会帮我们创建,如果有这个文件它会帮我们清空文件中的数据

//当不想要清空数据时,只需要在第二个参数后面里面写true,表示将新数据追加在文件末尾
FileOutputStream fos = new FileOutputStream("a.txt",true);
// 创建一个File对象,存放的是更改的文件路径
File file1 = new File("E:\\test\\a.txt");// 文件内容为hello
// 写入的数据存放在b.txt中
File file2 = new File("E:\\test\\b.txt");
// 创建一个字节输出流,打开并连接到一个实际的文件file
FileInputStream fis = new FileInputStream(file1);
// 创建一个字节输入流,并写入到指定file2中
FileOutputStream fos = new FileOutputStream(file2);
// 每次读取2个字节的数据,当fis.read()不等于-1也就是文件里面还有内容的时候,继续循环重复读取2个字节的数据
byte[] b = new byte[2];
//len为读取的数据大小,一般时数组的长度
int len = 0;
while ((len = fis.read(b)) != -1) {
	//从0开始,len为终点
	fos.write(b, 0, len);
}
//关闭流
fos.close();
fis.close();

BufferedInputStream

BufferedOutputStream

		// 创建一个File对象,存放的是更改的文件路径
		File file1 = new File("E:\\test\\a.txt");// 文件内容为hello world
		// 写入的数据存放在b.txt中
		File file2 = new File("E:\\test\\b.txt");
		// 创建一个字节输出流,打开并连接到一个实际的文件file
		FileInputStream fis = new FileInputStream(file1);
		// 创建一个字节输入流,并写入到指定file2中
		FileOutputStream fos = new FileOutputStream(file2);
		//缓冲区流包装文件输入流	
		BufferedInputStream bis = new BufferedInputStream(fis);
		//缓冲区流包装文件输出流	
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		// 每次读取2个字节的数据,当fis.read()不等于-1也就是文件里面还有内容的时候,继续循环重复读取2个字节的数据
		byte[] b = new byte[2];
		//len为读取的数据大小,一般时数组的长度
		int len = 0;
		while ((len = bis.read(b)) != -1) {
			//从0开始,len为终点
			bos.write(b, 0, len);
		}
		//关闭流
		bos.close();
		bis.close();

序列流

整合两个:SequenceInputStream(InputStream, InputStream)

FileInputStream fis1 = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("b.txt");
SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
FileOutputStream fos = new FileOutputStream("c.txt");

int len;
while ((len = sis.read()) != -1) {
	fos.write(len);
}
sis.close();
fos.close();

整合多个:SequenceInputStream(Enumeration)

FileInputStream fis1 = new FileInputStream("a.txt");
FileInputStream fis2 = new FileInputStream("b.txt");
FileInputStream fis3 = new FileInputStream("c.txt");

Vector<FileInputStream> v = new Vector<FileInputStream>();
v.add(fis1);
v.add(fis2);
v.add(fis3);
Enumeration<FileInputStream> en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);

FileOutputStream fos = new FileOutputStream("d.txt");

int len;
while ((len = sis.read()) != -1) {
	fos.write(len);
}
sis.close();
fos.close();

 

内存输出流

ByteArrayOutputStream

  • 该输出流可以向内存中写数据, 把内存当作一个缓冲区, 写出之后可以一次性获取出所有数据

  • 可以使用toByteArray()toString()把数据从内存中取出来

  • 可以不用关流

FileInputStream fis = new FileInputStream("a.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream();

int len;
while ((len = fis.read()) != -1) {
	baos.write(len);// 讲读取到的数据逐个写入内存
}

// byte[] byteArray = baos.toByteArray();//讲缓冲区的数据全部取出来,赋值给byteArray数组
// System.out.println(new String(byteArray));

System.out.println(baos.toString());// 直接打印内存中缓冲区里的数据

fis.close();

 

DataOutputStream

DataOutputStream

		File file1 = new File("E:\\test\\a.txt");
		FileOutputStream fos = new FileOutputStream(file1);
		//创建数据输出流
		DataOutputStream dos = new DataOutputStream(fos);
		//写入8中基本数据类型数据
		dos.writeByte((byte)1);
		dos.writeShort((short)10);
		dos.writeInt(100);
		dos.writeLong(1000L);
		dos.writeFloat(10000.1f);
		dos.writeDouble(100000.2d);
		dos.writeChar('A');
		dos.writeBoolean(true);
		//关闭流
		dos.close();
		fos.close();
		//读取8个基本数据类型数据
		FileInputStream fis = new FileInputStream(file1);
		//创建数据输入流
		DataInputStream dis = new DataInputStream(fis);
		System.out.println("byte类型数据:"+dis.readByte());
		System.out.println("short类型数据:"+dis.readShort());
		System.out.println("int类型数据:"+dis.readInt());
		System.out.println("long类型数据:"+dis.readLong());
		System.out.println("float类型数据:"+dis.readFloat());
		System.out.println("double类型数据:"+dis.readDouble());
		System.out.println("char类型数据:"+dis.readChar());
		System.out.println("boolean类型数据:"+dis.readBoolean());
		//关闭流
		dis.close();
		fis.close();

PrintStream

		File file1 = new File("E:\\test\\a.txt");
		FileOutputStream fos = new FileOutputStream(file1);
		//创建打印流
		PrintStream ps = new PrintStream(fos);
		//赋值变量
		String name = "aaa";
		int age = 18;
		String sex = "男";
		//打印数据到文件
		ps.println("name:"+name);
		ps.println("age:"+age);
		ps.println("sex:"+sex);
		//关闭流
		ps.close();

结果:

ObjectInputStream:反序列化

ObjectOutputStraem:序列化

串行化必须实现Serializable接口

package Demo9;

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

public class Student implements Serializable {

	String name;
	int age;
	String sex;

	public Student(String name, int age, String sex) {
		this.name = name;
		this.age = age;
		this.sex = sex;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]";
	}

	public static void main(String[] args) throws Exception {
		// 创建对象
		Student student1 = new Student("aaa", 18, "男");
		Student student2 = new Student("bbb", 19, "男");
		Student student3 = new Student("ccc", 20, "男");

		// 创建对象输出流
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
		// 创建对象输入流
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
		// 写入对象
		oos.writeObject(student1);
		oos.writeObject(student2);
		oos.writeObject(student3);
		// 读取对象
		Student stu1 = (Student) ois.readObject();
		Student stu2 = (Student) ois.readObject();
		Student stu3 = (Student) ois.readObject();
		// 打印对象信息
		System.out.println(stu1.toString());
		System.out.println(stu2.toString());
		System.out.println(stu3.toString());
		// 关闭流
		oos.close();
		ois.close();
	}

}

优化代码

// 创建对象,存入集合中
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("aaa", 18, "男"));
list.add(new Student("bbb", 19, "男"));
list.add(new Student("ccc", 20, "男"));
// 创建对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt"));
// 创建对象输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
// 写入集合对象
oos.writeObject(list);
// 读取集合对象
ArrayList<Student> listStudent = (ArrayList<Student>) ois.readObject();
// 打印对象信息
for (Student student : listStudent) {
	System.out.println(student.toString());
}
// 关闭流
oos.close();
ois.close();

打印流

  • 该流可以很方便的将对象的toString()结果输出, 并且自动加上换行, 而且可以使用自动刷出的模式

  • System.out就是一个PrintStream, 其默认向控制台输出信息

  • 只操作数据目的

字节输出流

PrintStream ps = System.out;
ps.println(97);					//其实底层用的是Integer.toString(x),将x转换为数字字符串打印
ps.println("xxx");
ps.println(new Person("张三", 23));
Person p = null;
ps.println(p);					//如果是null,就返回null,如果不是null,就调用对象的toString()

字符输出流

PrintWriter pw = new PrintWriter(new FileOutputStream("g.txt"), true);
pw.write(97);
pw.print("大家好");
pw.println("你好");				//自动刷出,只针对的是println方法
pw.close();

标准流

System.in是InputStream, 标准输入流, 默认可以从键盘输入读取字节数据,流对象只有一个可以不用关
System.out是PrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据

修改输入流: System.setIn(InputStream)
修改输出流: System.setOut(PrintStream)

System.setIn(new FileInputStream("a.txt"));	//修改标准输入流
System.setOut(new PrintStream("b.txt"));//修改标准输出流
			
InputStream in = System.in;//获取标准输入流,默认值向键盘,改变后指向a.txt
PrintStream ps = System.out;//获取标准输出流,默认值向控制台,改变后指向b.txt
int b;
while((b = in.read()) != -1) {			//从a.txt上读取数据
    ps.write(b);			//将数据写到b.txt上
}
//System.out.println();		//平常打印语句不用关闭流,因为它没有跟文件关联
in.close();
ps.close();					//跟文件关联起来,所以要关流

随机访问流

RandomAccessFile

  • RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。

  • 支持对随机访问文件的读取和写入。

  • 在创建对象时不会清空文件里的数据

构造方法的第二个参数是对文件操作的权限:

  • r:只读

  • rw:读和写

  • rws

  • rwd

RandomAccessFile baf = new RandomAccessFile("a.txt", "rw");
int read = baf.read();
System.out.println(read);
baf.seek(3);			//在指定位置设置指针,控制读或者写,多线程下载时可以增加效率	
baf.write(98);
baf.close();

Properties

  • 主要做配置文件

  • Properties 类表示了一个持久的属性集。

  • Properties 可保存在流中或从流中加载。

  • 属性列表中每个键及其对应值都是一个字符串。 

Properties prop = new Properties();
prop.put("name", "张三");
prop.put("age", "20");
		
System.out.println(prop);

public Object setProperty(String key,String value)

public String getProperty(String key)

public Enumeration<String> stringPropertyNames()

Properties prop = new Properties();
prop.setProperty("name", "张三");
prop.setProperty("age", "20");

Enumeration<String> en = (Enumeration<String>) prop.propertyNames();

while (en.hasMoreElements()) {
	String key = en.nextElement();
	String value = prop.getProperty(key);
        System.out.println(key + "=" + value);
}

Properties的load()和store()功能

Properties prop = new Properties();

prop.load(new FileInputStream("a.properties"));
prop.setProperty("name", "lisi");
prop.store(new FileOutputStream("a.properties"), null); // 第二个参数是对列表参数的描述,可以给值,也可以不给
System.out.println(prop);

 

字符流

  • 字符流是可以直接读写字符的IO流

  • 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出.

  • 不可以拷贝非纯文本的文件 

FileReader

FileWriter

FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
	
int ch;
while((ch = fr.read()) != -1) {
	fw.write(ch);
}
	
fr.close();
fw.close();

FileReader fr = new FileReader("aaa.txt");			//创建字符输入流,关联aaa.txt
FileWriter fw = new FileWriter("bbb.txt");			//创建字符输出流,关联bbb.txt
		
int len;
char[] arr = new char[1024*8];						//创建字符数组
while((len = fr.read(arr)) != -1) {					//将数据读到字符数组中
	fw.write(arr, 0, len);							//从字符数组将数据写到文件上
}
		
fr.close();											//关流释放资源
fw.close();	

 

BufferedReader

read()方法读取字符时会一次读取若干字符到缓冲区, 然后逐个返回给程序, 降低读取文件的次数, 提高效率

BufferedWriter

write()方法写出字符时会先写到缓冲区, 缓冲区写满时才会写到文件, 降低写文件的次数, 提高效率

BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));	//创建字符输入流对象,关联aaa.txt
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));	//创建字符输出流对象,关联bbb.txt
		
int ch;				
while((ch = br.read()) != -1) {		//read一次,会先将缓冲区读满,从缓冲去中一个一个的返给临时变量ch
	bw.write(ch);					//write一次,是将数据装到字符数组,装满后再一起写出去
}
		
br.close();							//关流
bw.close(); 

BufferedReader的readLine()方法可以读取一行字符(不包含换行符号)
BufferedWriter的newLine()可以输出一个跨平台的换行符号"\r\n"

BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("bbb.txt"));
String line;
while((line = br.readLine()) != null) {
	bw.write(line);
	//bw.write("\r\n");					//只支持windows系统
	bw.newLine();						//跨平台的
}
		
br.close();
bw.close(); 

 

使用指定的码表读写字符

InputStreamReader(字节流,编码表)

OutputStreamWriter(字节流,编码表)

//高效的用指定的编码表读
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("UTF-8.txt"), "UTF-8"));									

//高效的用指定的编码表写			
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GBK.txt"), "GBK"));									
				
int ch;
while((ch = br.read()) != -1) {
	bw.write(ch);
}
		
br.close();
bw.close();

 

 

总结:

  • InputStream 是一个抽象类,是所有字节输入流的基类,核心方法是read();OutputStream 是一个抽象类,是所有字节输出流的基类,核心方法是write()

  •  FileInputStream(文件字节流),构造器需要接受一个文件对象或者文件的路径

  • BufferedInputStream (缓冲字节流),构造器需要接受一个InputStream的子类对象,一般接受文件字节流对象。

  • PrintStream (打印流,输出流),把数据以自然语言的方式打印到文件中,构造器接受文件或者是另一个输出流

  • RandomAccessFile(随机文件读写流),既可以做输出流也可以做输入流,构造器需要接受一个文件对象或者文件的路径

  • ObjectInputStream (对象字节流),可以把对象保存成文件,构造器需要接受一个文件对象或者文件的路径

  • DataOutputStream (数据字节流),可以吧java中的基本数据型保存成文件,构造器需要接受一个文件对象或者文件的路径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值