面试题
- 什么是IO
- IO流的分类?
- IO流所使用的具体抽象类
- Java.io 包下常用的流(16个)
- FileInputStream详解
- FileOutputStream详解
- FileReader详解
- FileWriter详解
- BufferedReader详解
- BufferedWriter详解
- DataOutputStream详解
- DataInputStream详解
- Java字节流与字符流
- 字节流和字符流哪个好?怎么选择?
- 什么是缓冲区?有什么作用?
- 字符流和字节流有什么区别?
- 什么是Java序列化,如何实现Java序列化?
- PrintStream、BufferedWriter、PrintWriter的比较?
- BufferedReader属于哪种流,它主要是用来做什么的,它里面有那些经典的方法?
- 什么是节点流,什么是处理流,它们各有什么用处,处理流的创建有什么特征?
- 流是怎么关闭的?
- InputStream里的read()返回的是什么,read(byte[] data)是什么意思,返回的是什么值?
- OutputStream里面的write()是什么意思,write(byte b[], int off, int len)这个方法里面的三个参数分别是什么意思?
- 说说BIO、NIO和AIO的区别
什么是IO
I:Input
O:Output
通过IO可以完成硬盘文件的读和写。
IO流又叫输入输出流 ,输入和输出均是以内存作为参照物。
IO流的分类(从内存读写上)
- 输入流
- 输出流
以内存作为参照物,
往内存中去,叫做输入,或者叫做读。
从内存中出来,叫做输出,或者叫做写。
IO流的分类(从传输方式上)
字节流
按照字节的方式读取数据, 一次读取1个字节(byte),等同于一次读取8个二进制位。这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件。"类名"以Stream结尾的都是字节流。字节流的操作不会经过缓冲区(内存)而是直接操作文本本身的。
字符流
按照字符的方式读取数据, 一次读取一个字符(字符根据编码的不同,对应的字节也不同,如 UTF-8 编码中文汉字是 3 个字节,GBK编码中文汉字是 2 个字节),这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文件都无法读取。"类名"以"Reader/Writer"结尾的都是字符流 。字符流的操作会先经过缓冲区(内存)然后通过缓冲区再操作文件。
字节是个计算机看的,字符是给人看的。
IO流的分类(从节点处理上)
节点流
底层流,直接跟数据源连接。从一个特定的数据源读写数据,如FileReader、FileInputStream。
处理流
处理流使用了装饰器设计模式,对节点流进行包装,也叫包装流,对已存在的流(节点流或处理流)进行包装,提供更强大的读写功能,如:BuffededReader、BufferedInputStream。处理流包装节点流,可以消除不同节点流的实现差异,提供统一的接口完成输入输出。增加了缓冲的方式,提高输入输出的效率,提供多个方法来一次输入输出大批量数据,使用灵活。
IO流的分类(从数据操作上)
文件(File)
FileInputStream、FileOutputStream、FileReader、FileWriter
数组([])
字节数组(byte[]): ByteArrayInputStream、ByteArrayOutputStream
字符数组(char[]): CharArrayReader、CharArrayWriter
管道操作
PipedInputStream、PipedOutputStream、PipedReader、PipedWriter
基本数据类型
DataInputStream、DataOutputStream
缓冲操作
BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter
打印(输出)
PrintStream、PrintWriter
对象序列化反序列化
ObjectInputStream、ObjectOutputStream
转换(将字节流转换成字符流)
InputStreamReader、OutputStreamWriter
流操作示例
Stream的读写
FileInputStream:文件字节输入流,万能的,任何类型的文件都可以采用这个流来读,以字节的方式,完成输入的(读)的操作(硬盘 —> 内存)。
FileOutputStream:文件字节输出流,以字节的方式,完成输出的(写)的操作(硬盘 —> 内存)。
read():每次会读取一个字节。英文会读取一个字母,汉字读取半个字符或三分之一个字符。(因为GBK的一个汉字占两个字节,UTF-8的汉字占3个),读到文件末尾时read()方法会返回-1。
flush():清空缓冲区数据,数据先被读到了内存中,再将数据写到文件中,当数据读完的时候不代表数据已经写完了,因为还有一部分有可能会留在内存缓冲区中。此时如果调用了 close()方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭读写流之前先清空数据。
FileInputStream fis = null;
fis = new FileInputStream("C:\\Users\\Name.last\\Desktop\\1.txt");
byte[] bytes = new byte[1024];
int readCount;
// available 返回流当中的剩余的没有读到的字节数量
int available = fis.available();
// 如果返回流当中的剩余的没有读到的字节数量大于5,跳过5个字节不读
if(available >= 5) {
// skip 跳过几个字节不读
fis.skip(5);
}
// read 读取流
while((readCount = fis.read(bytes))!=-1){
// 把byte数组转换成字符串,读到多少个转换多少个
System.out.println(new String(bytes,0,readCount));
}
// close 关闭流
fis.close();
FileOutputStream fos = null;
// 不清空原文件的方式写入 则选择以追加的方式写入 不会清空原文件内容
// true表示追加
fos = new FileOutputStream("C:\\Users\\Name.last\\Desktop\\1.txt",true);
// 开始写
byte[] newBytes = {97,98,99,100};
// 将byte数组全部写出
fos.write(bytes); // abcd
// 将byte数组的一部分写出
fos.write(bytes,0,2); //ab
// 将字符串转换为byte数组
String s = "哈哈哈哈哈哈哈哈";
byte[] bytes1 = s.getBytes();
fos.write(bytes1);
// 清空流
fos.flush();
// 关闭流
fos.close();
File转化为InputStream
InputStream in = new FileInputStream(file);
处理流包装节点流
// 节点流
FileReader fileReader = new FileReader("e:\\test.txt")
// 处理流(包装流)
BufferedReader br = new BufferedReader(fileReader);