抽象基类: InputStream , OutputStream。数组
字节流能够操做任何数据。jvm
注意:字符流使用的数组时字符数组。char[] chs函数
字节流使用的数组时字节数组。byte[] bt学习
FileOutputStream fos = new FileOutputStream("a.txt");编码
fos.write("abcde");//直接将数据写入到了目的地。对象
fos.close();//只关闭资源。继承
FileInputStream fis = new FileInputStream("a.txt");图片
//fis.available();//获取关联的文件的字节数。内存
//若是文件体积不是很大。utf-8
//能够这样操做。
byte[] buf = new byte[fis.available()];//建立一个刚恰好的缓冲区。
//可是这有一个弊端,就是文件过大,大小超过jvm的内容空间时,会内存溢出。
fis.read(buf);
System.out.println(new String(buf));
需求:copy一个图片。
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("1.jpg"));
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("2.jpg"));
int by = 0;
while((by = bufis.read()) != -1) {
bufos.write(by);
}
bufos.close();
bufis.close();
目前学习的流对象:
字符流:
FileReader
FileWriter
BufferedReader
BufferedWriter
字节流:
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOutputStream
字节流的read() 方法读取一个字节。为何返回的不是byte类型,而是int类型呢?
由于read方法读到末尾时返回的是-1.
而在所操做的数据中很容易出现连续多个1的状况,而连续读到8个1,就是-1.
致使读取会提早中止。
因此将读到的一个字节给提高为一个int类型的数值,可是只保留原字节,并在剩余二进制位补0.
具体操做是:byte&255 or byte&0xff
对于write方法,能够一次写入一个字节,但接收的是一个int类型数值。
只写入该int类型的数值的最低一个字节(8位)。
简单说:read方法对读到的数据进行提高。write对操做的数据进行转换。
转换流:
特色:
1:是字节流和字符流之间的桥梁。
2:该流对象中能够对读取到的字节数据进行指定编码表的编码转换。
何时使用呢?
1:当字节和字符之间有转换动做时。
2:流操做的数据须要进行编码表的指定时。
具体的对象体现:
1:InputStreamReader:字节到字符的桥梁。
2:OutputStreamWriter:字符到字节的桥梁。
这两个流对象是字符流体系中的成员。
那么它们有转换做用,而自己又是字符流。因此在构造的时候,须要传入字节流对象进来。
构造函数:
InputStreamReader(InputStream):经过该构造函数初始化,使用的是本系统默认的编码表GBK
InputStreamReader(InputStream,String charSet):经过该构造函数初始化,能够指定编码表。
OutputStreamWriter(OutputStream):经过该构造函数初始化,使用的是本系统默认的编码表GBK。
OutputStreamWriter(OutputStream,String charSet):经过该构造函数初始化,能够指定编码表。
操做文件的字符流对象时转换流的子类。
Reader
--->InputStreamReader
--->FileReader
Writer
--->OutputStreamWriter
--->FileWriter
转换流中的read方法。已经融入了编码表,
在底层调用字节流的read方法时将获取的一个或者多个字节数据进行临时存储,并去查指定的编码表,若是编码表没有指定,查的是默认编码表。那么转换流的read方法就能够返回一个字符好比中文。
转换流已经完成了编码转换的动做,对于直接操做的文本文件的FileReader而言,就不用在从新定义了,只要继承该转换流,获取其方法,就能够直接操做文本文件中的字符数据了。
注意:
在使用FileReader操做文本数据时,该对象使用的是默认的编码表。若是要使用指定编码表时,必须使用转换流。
FileReader fr = new FileReader("a.txt");//操做a.txt中的数据使用本系统默认编码GBK。操做a.txt中的数据使用的也是本系统默认编码GBK。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
这两句的代码的意义相同。
若是a.txt中的文件中的字符数据时经过utf-8的形式编码。
那么在读取时,就必须指定编码表。
那么转换流必须使用。
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"utf-8");
流操做的基本规律。
1:明确数据源和数据汇(数据目的)。
实际上是为了明确输入流仍是输出流。
2:明确操做的数据是否时纯文本数据。
实际上是为了明确字符流仍是字节流。
数据源:键盘System.int , 硬盘 File 开头的流对象,内存(数组)。
数据汇:控制台System.out,硬盘 File 开头的流对象 , 内存(数组)。
需求:
1:将键盘录入的数据存储到一个文件中。
数据源:System.in
既然是源,使用的就是输入流,可用的体系有InputStream , Reader.
由于键盘录入进来的必定时纯文本数据,因此可使用专门操做字符数据的Reader。
发现System.in对应的流时字节读取流。因此要将其进行转换,将字节转成字符便可。
因此要使用Reader体系中:InputStreamReader
接下来,是否须要提升效率呢?若是须要,那么就加入字符流的缓冲区:BufferedReader
BufferedReader bur = new BufferedReader(new InputStreamReader(System.in));
数据汇:一个文件,硬盘。
既然时数据汇,那么必定时输出流,能够用的OutputStream,Writer.
往文件中存储的都是文本数据,那么可使用字符流较为方便:Writer.
由于操做的是一个文件。因此使用Writer中的FileWriter。
是否要提升效率呢?是,那么就使用BufferedWriter.
BufferedWriter bufr = new BufferedWriter(new FileWriter("a.txt"));
附加需求:但愿将这些文本数据按照指定的编码表存入文件中。
既然是文本数据,并且仍是写入到文件中,那么使用的体系仍是Writer。
由于要指定编码表,因此要使用Writer中的转换流,OutputStreamWriter。
是否要提升效率,是,选择BufferedWriter。
注意:虽然最终是文件,可是不能够选择FileWriter。由于该对象是使用默认编码表。
输出转换流要接收一个字节输出流进来,因此要使用OutputStream体系,而最终输出到一个文件中,
那么就要使用OutputStream体系中能够操做的文件的字节流对象:FileOutputStream。
//String charSet = System.getProperty("file.encoding");
String charSet = "utf-8";
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),charSet);