Java基础——IO流1

IO流

IO概述
  1. 概述:IO是input和output的缩写。
    输入和输出,表示的是数据的输入和数据的输出。
  2. 什么是输入和输出?
    数据的输入和输出就是相对于运行内存来说,数据从其他设备进入到运行内容就是输入,数据从运行内容到其他设备就是输出。
  3. 凡是操作数据输入和输出的对象所属的类型,都属于IO的范围。
  4. 分类:
    按照功能和流向有不同的类型
    按照功能分类:
    字节流
    字符流
    按照流向分类:
    输入流
    输出流
  5. 具体分类:
    字节输入流:inputStream ;字节输出流:outputStream
    字符输入流:Reader ;字符输出流:Writer
IO使用范围
  1. 导包:IO范围的类型都在io包中,需要先导包
  2. 处理异常:声明或者捕获
  3. 关流:关闭系统资源,节省资源
字节流
  1. 概述:操作字节信息输入和输出的流对象所属的类型。
  2. 字节输入流inputStream 字节输出流outputStream
InputStream
  1. 概述:字节输入流,本类是一个抽象父类,不能直接创建对象,需要通过子类创建
  2. 方法:
    -read() :从流中读取一个字节信息,将信息进行返回。
    注意:当前方法返回的是一个int类型的数据,而不是一个byte类型
    原因:默认在读取的字节信息前面加了24个0,强制变为一个int类型。因为读取的信息是一个字节信息,字节范围-128–127,如果读取了一个-1,可能是读取的数据,也可能是到达文件的末尾,所以为了区分是读取的数据,还是到达了文件的末尾,就默认在读取的数据前+20个0,强制变为正数,当读取返回了一个-1,肯定是到达了文件的末尾。
    -read(byte[] b) :从流对象中一次读取b.length个字节
    注意:
    (1)读取的数据存储到了到数组中
    (2)返回值是读取的字节个数
    -read(byte[] b, int off, int len) :从流中读取指定长度的数据到数组中
    -available() :将流中还没有读取的字节个数进行返回
    -close() :关闭流资源
FileInputStream
  1. 概述:属于字节输入流的子类,该类的对象可以将磁盘上的文件数据输入到内存中。
  2. 构造方法:
    (1)FileInputStream(File file):将file文件对象封装为文件字节输入流对象
    (2)FileInputStream(String str) :将str字符串所描述的文件封装为字节输入流对象
  3. 注意事项:
    不管是传入file对象还是字符串,对应的必须是某一个文件,不能是文件夹
    原因:因为文件中才可以存储数据,文件夹中不能直接存储数据,所以只能从文件中读取数据。
OutputStream
  1. 概述:字节输出流,将字节信息从内存中写出到其他设备。也是一个抽象类,需要通过子类创建对象。
  2. 方法:
    -write(int b) :将一个字节信息写出内存
    -write(byte[] b) :将一个数组中的信息写出内存
    -write(byte[] b, int off, int len) :将数组中的一部分信息写出内容
    -close() :关闭流资源
FileOutputStream
  1. 概述:文件字节输出流,将字节信息从内存中写出到目标磁盘文件中。
  2. 构造方法:
    -FileOutputStream(File file) :将file对象封装为一个字节输出流对象
    -FileOutputStream(String name) :将name字符串对应的文件封装为字节输出流对象
    -FileOutputStream((File file,boolean b) :将name字符串对应的文件封装为字节输出流对象,如果后面的值为false,表示替换写入信息
    -FileOutputStream(String name,boolean b) :将name字符串对应的文件封装为字节输出流对象,如果后面的值为true,表示追加写入信息
  3. 注意:
    不管是传入file对象还是字符串,对应的必须是某一个文件,不能是文件夹
    原因:因为文件中才可以存储数据,文件夹中不能直接存储数据,所以只能从文件中读取数据。
文件的copy
  1. 文件拷贝:将一个文件中的信息,复制到另外一个文件中
  2. 思路:
    先通过文件字节输出流将信息读取到内存中,再通过文件字节输出流将信息写出到另外一个目标文件中
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01 {

	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("a.txt");
		FileOutputStream fos = new FileOutputStream("a_copy.txt");
		int i ;
		while((i=fis.read())!=-1) {
			fos.write(i);
		}
		fis.close();
		fos.close();
	}

}

文件拷贝效率提升
  1. 拷贝效率慢原因:
    一个字节需要IO两次,读一次写一次,如果要拷问的字节有很多,需要iO文件个数两倍的次数。
  2. 提升思路:
    一次多读几个字节,多写几个字节。使用read(byte[] b)的方法和write(byte[] b)的方法,多读几个多写几个来提升效率。
  3. 使用大数组拷贝问题:
    数组将来需要再虚拟机中开辟空间, 如果数组的大小太大,将来对空间的要求比较高,可能空间也不够用,所以不能使用大数组拷贝。所以只能使用小数组拷贝文件。
  4. 使用小数组拷贝问题:
    但是使用小数组拷贝数据的时候,应该是读几个数据写出几个数据,所以需要使用write(byte[] b,0,len)这个方法来写出数据,避免多写出数据,造成发生数据的错误。
  5. 注意:
    使用小数组拷贝文件,一般指定数组的大小一般为1024的整数倍。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01 {

	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("maa.mp4");
		FileOutputStream fos = new FileOutputStream("maa2.mp4");
		byte[] bs = new byte[1024*8];
		int length ;
		while((length=fis.read(bs))!=-1) {
			fos.write(bs,0,length);
		}
		fis.close();
		fos.close();
	}

}

高效缓冲字节流
  1. 高效缓冲字节输入流:BufferedInputStream
  2. 高效缓冲字节输出流:BufferedOutPutStream
  3. 概述:这两个类型是包装类型,本类的对象不能读取和写出数据,但是这两个类型可以对基础的流对象进行加强(包装),加强之后,可以默认一次读取多个数据,写出多个数据,因为这两个类型中都维护了一个数组,来完成文件的拷贝。
  4. 构造方法:
    BufferedInputStream(InputStream in) :将基础的字节输入流对象进行包装成为一个高效字节输入流
    BufferedOutputStream(OutputStream out) :将基础的字节输出流对象进行包装
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01 {

	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("maa.mp4");
		FileOutputStream fos = new FileOutputStream("maa3.mp4");
		BufferedInputStream bis = new BufferedInputStream(fis);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		int i ;
		while((i=bis.read())!=-1) {
			bos.write(i);
		}
		bis.close();
		bos.close();
	}

}

close和flush的区别
  1. close方法作用:
    (1)可以将数据从缓冲区中刷新到目标文件中
    (2)可以关闭流资源
  2. flush方法作用:
    (1)只能将数据从缓冲区刷新到目标文件中
  3. 两者关系:
    在使用close方法关闭流资源之前,系统会默认调用flush方法先刷新数据
字符流

使用的原因

  1. 如果想要一次写一个字符串,使用字节流可以完成,但是需要将字符串进行转换为字节数组。(操作稍微有点麻烦)
  2. 如果想要从一个文件中读取信息,进行展示
    (1)这个文件中如果是全英文,可以一次读取一个字节,进行转换
    (2)如果全是中文,可以使用字节流一次读取两个字节,将两个字节转为一个字符串,进行展示
    (3)如果文件中是中英文混杂,这时不知道是读取几个字节进行转换,容易发生乱码。

概述

  1. 字符流:可以以字符为单位操作数据的输入和输出的对象所属的类型
  2. 分类
    字符输入流 Reader
    字符输出流 Writer
Reader
  1. 字符输入流,也是一个抽象父类,不能直接创建对象
  2. 方法:
    -read() :读取一个字符信息,将读到的信息进行返回
    -read(char[] c) :读取c.length个字符到数组中,返回的是读取的字符个数
    -read(char[] c,int offset,int len):读取一部分字符到数组中
    -close() :关闭流资源
  3. 使用子类创建对象:FileReader
    -FileReader(File file)
    -FileReader(String fileName)
  4. 不仅可以读取全中文以及全英文,还可以读取中英文混杂的字符。
Writer
  1. 字符输出流,是一个抽象父类,不能直接创建对象
  2. 方法:
    -write(int c) :写出一个字符
    -write(String str) :写出一个字符串
    -write(char[] cbuf) :写出一个数组中的字符
    -write(char[] cbuf, int off, int len) :写出数组的一部分到目标文件
    -write(String str, int off, int len) :写出字符串的一部分
  3. FileWriter:文件字符输出流
    -FileWriter(File file)
    -FileWriter(String fileName)
  4. 注意:
    (1)写出的目标必须是一个文件,不能是一个文件夹
    (2)字符输出流类型中,也是维护了一个数组,使用之后,需要使用刷新方法或者关流方法,将数据刷新到目标文件中
文件的copy
  1. 思路:先通过字符输入流将字符信息读取到内存中,再通过字符输出流将信息从内存写出到目标文件中。
  2. 使用的场景:
    如果只需要拷贝文件,使用字节流拷贝即可
    如果需要查看某个文件中的信息,或者修改某个文件中的信息,使用字符流来读,来写出信息。
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo03 {

	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("a.txt");
		FileWriter fw = new FileWriter("a_copy.txt");
		int i;
		while((i=fr.read())!=-1) {
			fw.write(i);
		}
		fr.close();
		fw.close();
	}

}
字符流使用小数组拷贝文件
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo03 {

	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("b.txt");
		FileWriter fw = new FileWriter("b_copy.txt");
		char[] ch = new char[1024*8];
		int i;
		while((i=fr.read(ch))!=-1) {
			fw.write(ch,0,i);
		}
		fr.close();
		fw.close();
	}

}

字符流拷贝非纯文本文件
  1. 纯文本文件:全是以字符的方式来表示数据的文件
  2. 非纯文本文件:图片,视频,音频等不是以字符的方式来表示数据的文件
  3. 结论:字符流不能拷贝非纯文本文件
  4. 原因:
    使用字符流拷贝数据的话,需要先通过字节流将字节信息输入到内存中,再通过查询编码表将字节信息转成对应的字符。非纯文本文件中都很多字节,读取的字节信息不一定和编码表中的字符对应,如果没有字符对应这个读取的字节,使用?字符来代替。在写出的时候,继续将?对应的字节写出到了目标文件中。
高效缓冲字符流
  1. 类型:BufferedReader和BufferedWriter
  2. 概述:都是包装类型,需要对基础的字符流对象进行包装。包装之后,一次也可以读取多个字符,可以写出多个字符。
  3. 构造:BufferedReader(Reader in)
    方法:readLine() :一次可以从输入流中读取一行信息
    返回值就是读取的这一行数据,如果到达文件的末尾,返回null
  4. 构造:BufferedWriter(Writer out)
    方法:newLine() :表示在文件中进行换行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值