io流分为字符流和字节流
字节流是万能流,可以处理任何数据,包含图片、视频、文字等,传输单位为字节
字符流只能读取文本数据,传输单位为字符
(一)“字节”的定义
字节(Byte)是一种计量单位,表示数据量多少,它是计算机信息技术用于计量存储容量的一种计量单位。
(二)“字符”的定义
字符是指计算机中使用的文字和符号,比如1、2、3、A、B、C、~!·#¥%……—*()——+、等等。
(三)“字节”与“字符”的区别
它们完全不是一个位面的概念,所以两者之间没有“区别”这个说法。
不同编码里,字符和字节的对应关系不同:
①ASCII码中:一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。
一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数,换算为十进制。最小值0,最大值255。
②UTF-8编码中:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。
③Unicode编码中:一个英文字符等于两个字节,一个中文(含繁体)等于两个字节。
符号:英文标点占一个字节;中文标点占两个字节。
举例:英文句号“.”占1个字节的大小;中文句号“。”占2个字节的大小。
④UTF-16编码中:一个英文字母字符或一个汉字字符存储都需要2个字节(Unicode扩展区的一些汉字存储需要4个字节)。
⑤UTF-32编码中:世界上任何字符的存储都需要4个字节。
摘自https://www.cnblogs.com/chenmingjun/p/8118083.html
读操作用到输入流,写操作用到输出流
先来看字节流
InputStream和OutputStream
InputStream是输入字节流,常用的有FileInputStream和BufferendInputStream
InputStream作为字节流的基类,有几个通用的方法:
read(byte[] b):从流中读取b的长度个字节的数据存储到b中,返回结果是读取的字节个数(当再次读时,如果返回-1说明到了结尾,没有了数据)
read(byte[] b, int off, int len):从流中从off的位置开始读取len个字节的数据存储到b中,返回结果是实际读取到的字节个数(当再次读时,如果返回-1说明到了结尾,没有了数据)
close():关闭流,释放资源。
FileInputStream继承了InputStream抽象类
FileInputStream主要用来操作文件输入流,它除了可以使用基类定义的函数外,它还实现了基类的read()函数(无参的):
read():从流中读取1个字节的数据,返回结果是一个int,(如果编码是以一个字节一个字符的,可以尝试转成char,用来查看数据)。
BufferendInputStream不是InputStream的直接子类,是InputStream的子类FilterInputStream的子类
带有缓冲的意思,普通的读是从硬盘里面读,而带有缓冲区之后,BufferedInputStream已经提前将数据封装到内存中,内存中操作数据要快,所以它的效率要要非缓冲的要高。它除了可以使用基类定义的函数外,它还实现了基类的read()函数(无参的):
read():从流中读取1个字节的数据,返回结果是一个int,(如果编码是以一个字节一个字符的,可以尝试转成char,用来查看数据)。
再来看字符流
Reader和Writer
Reader是输入字节流,常用的有Reader、BufferendReader、InputStreamReader、FileReader
Reader是字符输入流的抽象基类 ,它定义了以下几个函数:
read() :读取单个字符,返回结果是一个int,需要转成char;到达流的末尾时,返回-1
read(char[] cbuf):读取cbuf的长度个字符到cbuf这种,返回结果是读取的字符数,到达流的末尾时,返回-1
close() :关闭流,释放占用的系统资源。
InputStreamReader 转换流。可以把InputStream中的字节数据流根据字符编码方式转成字符数据流。它除了可以使用基类定义的函数,它自己还实现了以下函数:
read(char[] cbuf, int offset, int length) :从offset位置开始,读取length个字符到cbuf中,返回结果是实际读取的字符数,到达流的末尾时,返回-1
FileReader 可以把FileInputStream中的字节数据转成根据字符编码方式转成字符数据流。
BufferedReader可以把字符输入流进行封装,将数据进行缓冲,提高读取效率。它除了可以使用基类定义的函数,它自己还实现了以下函数:
read(char[] cbuf, int offset, int length) :从offset位置开始,读取length个字符到cbuf中,返回结果是实际读取的字符数,到达流的末尾时,返回-1
readLine() :读取一个文本行,以行结束符作为末尾,返回结果是读取的字符串。如果已到达流末尾,则返回 null
练习一下吧
package com.cn;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 读取txt文件
* 一次读一行
* @author ylq
*
*/
public class BufferendReaderDemo {
public static void main(String[] args) {
//文件路径
String filePath="E:/hh.txt";
File file=new File(filePath);
BufferedReader reader = null;//字符输入流进行读取操作读取
String tempString = null;//每一行的内容
int line =1;//行号
try {
//输入字节流,FileInputStream主要用来操作文件输入流
FileInputStream intput = new FileInputStream(file);
// System.out.println("以行为单位读取文件内容,一次读一整行:")
//InputStreamReader是转换流,将字节流转成字符流
reader = new BufferedReader(new InputStreamReader(intput));
while ((tempString = reader.readLine()) != null) {
System.out.println("第"+ line + "行:" +tempString);
line ++ ;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(reader != null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}