Day18 IO

IO

流:数据传递的统称
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
标准输入

InputStream in = System.in;
in.read();

标准输出

PrintStream是OutputStream的子类
PrintStream out = System.out;
out.println()
分类

处理数据类型不同:字符流与字节流
数据流向不同:输入流与输出流(相对内存)
功能不同:节点流和处理流

抽象类

在这里插入图片描述

文件流

InputStream

FileInputStream 字节输入流
输入/读取 : 必须先找到这个文件
绝对位置 : 当前文件系统的根目录为准
相对位置 : 以当前文件所在目录为准 ./
./ 当前目录 , …/ 上级目录 , …/…/…/
eclipse中 ./ 是当前项目 D:\workspace\w20210322_17\JavaSE_08_IO

close();
read();
read(byte[] bytes);
read(byte[] bytes  , int start , int length);
// 会匹配当前操作系统,window \\ linux /
		System.out.println(File.separator);
		// 创建字节输入流对象
		// 相对
		FileInputStream fis = new FileInputStream("./src/com/Test_01.java");
		// read 读取下一个字节,如果到达文件末尾,返回 -1  ,默认光标在顶端,读一下,向下移动一位,并返回下一位的值
		int i1 = fis.read();
		System.out.println((char)i1);

		// 循环读取
		int temp = 0;
		while ( (temp=fis.read()) != -1 ) {
			System.out.print((char)temp);
		}

完整需要try…catch异常,关闭流,提升变量


	public static void main(String[] args) {
		// 提升变量至main方法中,否则finally中访问不到
		// 局部变量没有默认值,并且try有不执行情况,所以默认赋值null
		FileInputStream fis = null ;
		try {
			// 创建对象并获取文件流
			 fis = new FileInputStream("./src/com/Test_01.java");
			// 循环读取
			int temp = 0;
			while ((temp = fis.read()) != -1) {
				System.out.print((char) temp);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			// 关闭资源
			try {
				//  防止未找到文件,导致空指针异常
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

jdk1.8后try可以自动关闭流
使用字节数组可以一次性取出多个字节提高效率,但是如果字节数组过大,会留有空位,如果小于内容则第二次读取内容会重复,为了解决这个问题,需要额外传入两个变量控制读取个数
输出时使用String的构造方法可以将字节数组转换为字符串

		try (
		// 创建对象并获取文件流
		FileInputStream fis = new FileInputStream("./src/com/Test_01.java");) {
			// 循环读取
			byte[] bytes = new byte[100];
			int temp = 0;
			while ((temp = fis.read(bytes)) != -1) {
				// 不能直接把数组转换 为字符串,否则有多种情况会导致数据不准确
				// 比如 : 1 数组长1000  , 而文件中字节只有 100 ,  则 数组中还有900个0 没有添加数据,此时如果全部转换为字符串,数据就不准确了
				// 比如 : 2 数组长100 , 而文件中字节有150 , 则 第二次读的时候,只能读取到50个,而数组中第一次读取的后50个元素还在数组中,所以导致数据冗余
				// 所以最好是 读了多少 就转换多少,而 该方法返回值 就是当前次读取的个数
				// System.out.print(new String(bytes));
				System.out.print(new String(bytes, 0, temp));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
OutputStream

FileOutputStream 字节输出流
常用方法

close();
flush();//清空缓存区
write(int b);
write(byte[] bytes);
write(byte[] bytes  , int start , int length);

输出流,如果目标文件不存在 会自动创建该文件,注意 不会创建目录,如果目录不存在就会报错
覆盖与追加
构造方法 :
FileOutputStream(String) : 只传递需要写出的文件路径,默认覆盖写出
FileOutputStream(String,boolean) : 只传递需要写出的文件路径,第二个参数,如果为true 就是追加写出,false是覆盖写出
字符串转换为字节数组 getBytes()

		// 创建对象 默认覆盖写出
//		FileOutputStream fos = new FileOutputStream("D:/123.txt");
		// 追加
		 FileOutputStream fos = new FileOutputStream("D:/123.txt",true);
		
		// 写出单个内容
		fos.write(97);
		byte[] bytes = {48,49,50,51};
		// 写出整个数组
		fos.write(bytes);
		// 写出一部分
		fos.write(bytes, 0, 3);
		// 写出字符串
		String str ="你好吗";
		bytes = str.getBytes();
		fos.write(bytes);
		// 刷缓存
		fos.flush();
		// 关闭
		fos.close();
Reader

FileReader字符输入流
方法与字节输入流一致
可以解决输入数据汉字的乱码问题,一般用于纯文本文件,像压缩包,图片,视频,音乐等 还是要使用字节,使用字符会出现问题

	try (
				// 打开字符输入流
					FileReader fr = new FileReader("./src/com/Test_01.java");
					){
				char[] chars = new char[100];
				int temp = 0;
				while ( (temp = fr.read(chars)) != -1 ) {
					System.out.print(new String(chars,0,temp));
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
Writer

FileWriter 字符输出流
除与字节输出流相等的方法外还有

write(String str);
write(String str  , int start , int length);
append(char ch);
		// 字符输出流 用于同字节输出流,只是写出方法是字符数组 和 字符串
		try (
				FileWriter fw = new FileWriter("D:/123.txt");
				){
			fw.write("你好吗");
			// 换行符
			fw.write("\n");
			fw.write("吃了吗");
			fw.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值