1.字节流和字符流

1.字节流

字节流

图片 1

1.1.字节输出流output

字节流主要是操作byte类型数据,以byte数组为准,主要操作类就是OutputStream、InputStream

图片 2

1.1.1.数据写入文件中

字节输出流:OutputStream

缓冲流是为了读取和写入的速度,提高效率主要包括:字节缓冲流和字符缓冲流

通过api查找 output 。找到很多,其中 java.io.OutputStream ,OutputStream:
输出字节流的超类。

OutputStream是整个IO包中字节输出流的最大父类,此类的定义如下:

字节缓冲流:

根据流的方向,共有2个:字节缓冲输出流BufferedOutputStream和字节缓冲输入流BufferedInputStream,它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度

构造方法:public BufferedOutputStream(OutputStream out);

//创建基本的字节输出流

FileOutputStream fileOut=newFileOutputStream(“abc.txt”);

//使用高效的流,把基本的流进行封装,实现速度的提升

BufferedOutputStream out=newBufferedOutputStream(fileOut);

//2,写数据

out.write(“hello”.getBytes());

//3,关闭流

out.close();

}

构造方法:public BufferedInputStream(InputStream in);

FileInputStream fileIn =newFileInputStream(“abc.txt”);

//把基本的流包装成高效的流

BufferedInputStream in =newBufferedInputStream(fileIn);

//2,读数据

int ch = -1;

while( (ch = in.read()) != -1 ) {

//打印

System.out.print((char)ch);

}

//3,关闭

in.close();

高效的实现复制文件;

BufferedInputStream in
=newBufferedInputStream(newFileInputStream(“c:\a.txt”));

//2,指定目的地

BufferedOutputStream
out=newBufferedOutputStream(newFileOutputStream(“c:\b.txt”));

//3,读数据

byte[] buffer =newbyte[1024];

intlen = -1;

while( (len = in.read(buffer)) != -1) {

//4,写数据

out.write(buffer, 0, len);

}

//5,关闭流

in.close();

out.close();

小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:664389243
这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!

public abstract class OutputStream extends Object implements Closeable,Flushable

字符缓冲流:

字符缓冲输入流BufferedReader。字符缓冲输出流BufferedWriter

基本特点:

从以上的定义可以发现,此类是一个抽象类,如果想要使用此类的话,则首先必须通过子类实例化对象,那么如果现在要操作的是一个文件,则可以使用:FileOutputStream类。通过向上转型之后,可以为OutputStream实例化

**BufferedWriter**

//创建流

//基本字符输出流

FileWriter fileOut =newFileWriter(“file.txt”);

//把基本的流进行包装

BufferedWriter out =newBufferedWriter(fileOut);

//2,写数据

for(inti=0; i<5; i++) {

out.write(“hello”);

out.newLine();//写入换行

}

//3,关闭流

out.close();

}

1、操作的数据都是字节。

Closeable表示可以关闭的操作,因为程序运行到最后肯定要关闭

Buffered**Reader**

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

publicStringreadLine()读取一个文本行,包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回null

//1,创建流

BufferedReader in =newBufferedReader(newFileReader(“file.txt”));

//2,读数据

//一次读取文本中一行的字符串内容

String line =null;

while( (line = in.readLine()) !=null){

System.out.println(line);

}

//3,关闭流

in.close();

2、定义了输出字节流的基本共性功能。

Flushable:表示刷新,清空内存中的数据

使用缓冲流高效的完成文件的复制

//1,指定数据源,是数据源中读数据,采用输入流

BufferedReader in =newBufferedReader(newFileReader(“file.txt”));

//2,指定目的地,是把数据写入目的地,采用输出流

BufferedWriter out
=newBufferedWriter(newFileWriter(“copyFile.txt”));

//3,读数据

String line =null;

while( (line = in.readLine()) !=null) {

//4,写数据

out.write(line);

//写入换行符号

out.newLine();}

//5,关闭流

out.close(); in.close();

}

这么多流该如何选择:

目的设备:

硬盘:文件File开头。

内存:数组,字符串。

屏幕:System.out

网络:Socket

完全可以明确具体要使用哪个流对象。

3、输出流中定义都是写write方法。操作字节数组write,操作单个字节 write 。

FileOutputStream类的构造方法如下:

知识点总结

字节流

字节输入流InputStream

FileInputStream操作文件的字节输入流

BufferedInputStream高效的字节输入流

字节输出流OutputStream

FileOutputStream操作文件的字节输出流

BufferedOutputStream高效的字节输出流

字符流

字符输入流Reader

FileReader操作文件的字符输入流

BufferedReader高效的字符输入流

InputStreamReader输入操作的转换流(把字节流封装成字符流)

字符输出流Writer

FileWriter操作文件的字符输出流

BufferedWriter高效的字符输出流

OutputStreamWriter输出操作的转换流(把字节流封装成字符流)

方法:

读数据方法:

read()一次读一个字节或字符的方法

read(byte[]char[])一次读一个数组数据的方法

readLine()一次读一行字符串的方法(BufferedReader类特有方法)

readObject()从流中读取对象(ObjectInputStream特有方法)

写数据方法:

write(int)一次写一个字节或字符到文件中

write(byte[] char[])一次写一个数组数据到文件中

write(String)一次写一个字符串内容到文件中

uwriteObject(Object )写对象到流中(ObjectOutputStream类特有方法)

unewLine()写一个换行符号(BufferedWriter类特有方法)

向文件中写入数据的过程

1,创建输出流对象

2,写数据到文件

3,关闭输出流

从文件中读数据的过程

1,创建输入流对象

2,从文件中读数据

3,关闭输入流

l文件复制的过程

1,创建输入流(数据源)

2,创建输出流(目的地)

3,从输入流中读数据

4,通过输出流,把数据写入目的地

5,关闭流

子类有规律:所有的子类名称后缀是父类名,前缀名是这个流对象功能。

public FileOutputStream(File file)throws FileNotFoundException

想要操作文件: FileOutputStream

写数据:

1publicclassFileOutputStreamDemo {2publicstaticvoidmain(String[]
args)throwsIOException
{3//需求:将数据写入到文件中。4//创建存储数据的文件。5Filefile=newFile(“c:\file.txt”);6//创建一个用于操作文件的字节输出流对象。一创建就必须明确数据存储目的地。7//输出流目的是文件,会自动创建。如果文件存在,则覆盖。8FileOutputStream
fos =newFileOutputStream;9//调用父类中的write方法。10byte[] data
=”abcde”.getBytes();11fos.write;12//关闭流资源。13fos.close();14}15}

1.1.2.给文件中续写和换行

1importjava.io.File;

我们知道直接 new
FileOutputStream这样创建对象,会覆盖原有的文件,那么我们想在原有的文件中续写内容怎么办呢?继续查阅FileOutputStream的API。发现在FileOutputStream的构造函数中,可以接受一个boolean类型的值,如果值true,就会在文件末位继续添加。

2importjava.io.FileOutputStream;

1publicclassFileOutputStreamDemo2 {2publicstaticvoidmain(String[]
args)throwsException
{3Filefile=newFile(“c:\file.txt”);4FileOutputStream fos
=newFileOutputStream(file,true);5String str
=”rn”+”itcast”;6fos.write(str.getBytes;7fos.close();8}9}

3importjava.io.IOException;

1.1.3.IO异常的处理

4importjava.io.OutputStream;

我们在开发中应该如何处理这些异常呢?

5

1publicclassFileOutputStreamDemo3 {2publicstaticvoidmain(String[]
args)
{34Filefile=newFile(“c:\file.txt”);5//定义FileOutputStream的引用6FileOutputStream
fos =null;7try{8//创建FileOutputStream对象9fos
=newFileOutputStream;10//写出数据11fos.write(“abcde”.getBytes;1213}catch(IOException
e) {14System.out.println(e.toString()
+”—-“);15}finally{16//一定要判断fos是否为null,只有不为null时,才可以关闭资源17if(fos
!=null) {18try{19fos.close();20}catch(IOException e)
{21thrownewRuntimeException;22}23}24}25}26}

6publicclassTest11 {

1.2.字节输入流Input

7publicstaticvoidmain(String[] args)throwsIOException {

1.2.1.读取数据read方法

8File f =newFile(“d:” + File.separator+”test.txt”);

通过api查找 input 。 java.io.InputStream。
InputStream:字节输入流的超类。

9OutputStream out=newFileOutputStream(f);//如果文件不存在会自动创建

常见功能:

10String str=”Hello World”;

int read():读取一个字节并返回,没有字节返回-1.

11byte[] b=str.getBytes();

int read: 读取一定量的字节数,并存储到字节数组中,返回读取到的字节数。

12out.write(b);//因为是字节流,所以要转化成字节数组进行输出

用于读取文件的字节输入流对象:FileInputStream。

13out.close();

1publicclassFileInputStreamDemo {2publicstaticvoidmain(String[]
args)throwsIOException
{3Filefile=newFile(“c:\file.txt”);4//创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。5FileInputStream
fis =newFileInputStream;6//读取数据。使用 read();一次读一个字节。7intch
=0;8while((ch=fis.read{9System.out.println(“ch=”+;10}11//
关闭资源。12fis.close();13}14}

14}

1.2.2.读取数据read方法

15}

在读取文件中的数据时,调用 read
方法,每次只能读取一个,太麻烦了,于是我们可以定义数组作为临时的存储容器,这时可以调用重载的
read 方法,一次可以读取多个字符。

1publicclassFileInputStreamDemo2 {2publicstaticvoidmain(String[]
args)throwsIOException {3/*

也可以一个字节一个字节进行输出,如下:

4 * 演示第二个读取方法, read;

5 */6Filefile=newFile(“c:\file.txt”);7//
创建一个字节输入流对象,必须明确数据源,其实就是创建字节读取流和数据源相关联。8FileInputStream
fis =newFileInputStream;9//创建一个字节数组。10byte[] buf
=newbyte[1024];//长度可以定义成1024的整数倍。 11intlen
=0;12while((len=fis.read!=-1){13System.out.println(newString(buf,0,len));14}15fis.close();16}17}

1importjava.io.File;

2.字符流

2importjava.io.FileOutputStream;

经过前面的学习,我们基本掌握的文件的读写操作,在操作过程中字节流可以操作所有数据,可是当我们操作的文件中有中文字符,并且需要对中文字符做出处理时怎么办呢?

3importjava.io.IOException;

2.1.字节流读取问题

4importjava.io.OutputStream;

通过以下程序读取带有中文件的文件。

5

1publicclassCharStreamDemo{2publicstaticvoidmain(String[]
args)throwsIOException{3//给文件中写中文4writeCNText();5//读取文件中的中文6readCNText();7}8//读取中文9publicstaticvoidreadCNText()throwsIOException{10FileInputStream
fis =newFileInputStream(“c:\cn.txt”);11intch =0;12while((ch =
fis.read{13System.out.println;14}15}16//写中文17publicstaticvoidwriteCNText()throwsIOException{18FileOutputStream
fos
=newFileOutputStream(“c:\cn.txt”);19fos.write(“a传智播客欢迎你”.getBytes;20fos.close();21}22}

6publicclassTest11 {

上面程序在读取含有中文的文件时,我们并没有看到具体的中文,而是看到一些数字,这是什么原因呢?既然看不到中文,那么我们如何对其中的中文做处理呢?要解决这个问题,我们必须研究下字符的编码过程。

7publicstaticvoidmain(String[] args)throwsIOException {

2.2.编码表

8File f =newFile(“d:” + File.separator+”test.txt”);

我们知道计算机底层数据存储的都是二进制数据,而我们生活中的各种各样的数据,如何才能和计算机中存储的二进制数据对应起来呢?这时老美他们就把每一个字符和一个整数对应起来,就形成了一张编码表,老美他们的编码表就是ASCII表。其中就是各种英文字符对应的编码。

9OutputStream out=newFileOutputStream(f);//如果文件不存在会自动创建

编码表:其实就是生活中字符和计算机二进制的对应关系表。

10String str=”Hello World”;

1、ascii: 一个字节中的7位就可以表示。对应的字节都是正数。0-xxxxxxx

11byte[] b=str.getBytes();

2、iso8859-1:拉丁码表 latin,用了一个字节用的8位。1-xxxxxxx 负数。

12for(inti=0;i

3、GB2312:简体中文码表。包含6000-7000中文和符号。用两个字节表示。两个字节都是开头为1
,两个字节都是负数。

13out.write(b[i]);

GBK:目前最常用的中文码表,2万的中文和符号。用两个字节表示,其中的一部分文字,第一个字节开头是1,第二字节开头是0

14}

GB18030:最新的中文码表,目前还没有正式使用。

15out.close();

4、unicode:国际标准码表:无论是什么文字,都用两个字节存储。

16}

Java中的char类型用的就是这个码表。char c = ‘a’;占两个字节。

17}

Java中的字符串是按照系统默认码表来解析的。简体中文版
字符串默认的码表是GBK。

5、UTF-8:基于unicode,一个字节就可以存储数据,不要用两个字节存储,而且这个码表更加的标准化,在每一个字节头加入了编码信息(后期到api中查找)。

以上输出只会进行覆盖,如果要追加的话,请看FileOutputStream类的另一个构造方法:

能识别中文的码表:GBK、UTF-8;正因为识别中文码表不唯一,涉及到了编码解码问题。对于我们开发而言;常见的编码
GBK UTF-8 ISO8859-1

public FileOutputStream(File file,boolean append)throws FileNotFoundException

文字—> :编码。

在构造方法中,如果将append的值设置为true,则表示在文件的末尾追加内容。

—>文字 : 解码。

2.3.FileReader类介绍

1importjava.io.File;

上述程序中我们读取拥有中文的文件时,使用的字节流在读取,那么我们读取到的都是一个一个字节。只要把这些字节去查阅对应的编码表,就能够得到与之对应的字符。API中是否给我们已经提供了读取相应字符的功能流对象呢?

2importjava.io.FileOutputStream;

查阅FileInputStream的 API ,发现 FileInputStream
用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用
FileReader 。如果读取字符流,要使用 FileReader , FileReader 是什么呢?

3importjava.io.IOException;

打开FileReader的 API
介绍。用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的,原来FileReader
用于读取字符流。使用 FileReader 时,了解它的功能,看它所属的体系顶层。

4importjava.io.OutputStream;

Reader:读取字符流的抽象超类。

5

read():读取单个字符并返回

6publicclassTest11 {

read:将数据读取到数组中,并返回读取的个数。

7publicstaticvoidmain(String[] args)throwsIOException {

1publicclassCharStreamDemo{2publicstaticvoidmain(String[]
args)throwsIOException{3//给文件中写中文4writeCNText();5//读取文件中的中文6readCNText();7}8//读取中文9publicstaticvoidreadCNText()throwsIOException{10FileReader
fr =newFileReader(“D:\test\cn.txt”);11intch =0;12while((ch =
fr.read{13//输出的字符对应的编码值14System.out.println;15//输出字符本身16System.out.println;17}18}19//写中文20publicstaticvoidwriteCNText()throwsIOException{21FileOutputStream
fos
=newFileOutputStream(“D:\test\cn.txt”);22fos.write(“a传智播客欢迎你”.getBytes;23fos.close();24}25}

8File f =newFile(“d:” + File.separator+”test.txt”);

2.4.FileWriter类介绍

9OutputStream out=newFileOutputStream(f,true);//追加内容

既然有专门用于读取字符的流对象,那么肯定也有写的字符流对象,查阅 API
,发现有一个Writer 类, Writer
是写入字符流的抽象类。其中描述了相应的写的动作。

10String str=”rnHello World”;

1publicclassFileWriterDemo{2publicstaticvoidmain(String[]
args)throwsIOException{3//演示FileWriter
用于操作文件的便捷类。4FileWriter fw
=newFileWriter(“d:\text\fw.txt”);56fw.write;//这些文字都要先编码。都写入到了流的缓冲区中。78fw.flush();910fw.close();11}12}

11byte[] b=str.getBytes();

2.5.flush的区别

12for(inti=0;i

flush():
将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用。

13out.write(b[i]);

close():
关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后在关闭流。流不可以使用。如果写入数据多,一定要一边写一边刷新,最后一次可以不刷新,由
close 完成刷新并关闭。

14}

3.转换流

15out.close();

学习完了使用字符流对文件的简单操作后,在学习字符流的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个
InputStreamReader 或者 OutputStreamWriter ,这又是什么意思呢?

16}

3.1.OutputSreamWriter类

17}

需求:既然识别中文的码表有两个, GBK 、 UTF-8 等,能不能将中文数据按照
utf-8 的方式进行文件的存储呢?

还能使用 FileWriter 吗?不能使用了,因为 FileWriter 中默认的是 GBK
。通过 FileWriter 的api 描述,要指定编码表这些值,需要使用
OutputStreamWriter

文件中换行为:rn

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset
将要写入流中的字符编码成字节。它的作用的就是,将字符串按照指定的编码表转成字节,在使用字节流将这些字节写出去。

字节输入流:InputStream

1publicstaticvoidwriteCN()throwsException{2//创建与文件关联的字节输出流对象3FileOutputStream
fos
=newFileOutputStream(“c:\cn8.txt”);4//创建可以把字符转成字节的转换流对象,并指定编码5OutputStreamWriter
osw
=newOutputStreamWriter(fos,”utf-8″);6//调用转换流,把文字写出去,其实是写到转换流的缓冲区中7osw.write;//写入缓冲区。8osw.close();9}

既然程序可以向文件中写入内容,则就可以通过InputStream从文件中把内容读取进来,首先来看InputStream类的定义:

OutputStreamWriter 流对象,它到底如何把字符转成字节输出的呢?

public abstract class InputStream extends Object implements Closeable

其实在 OutputStreamWriter 流中维护自己的缓冲区,当我们调用
OutputStreamWriter 对象的write
方法时,会拿着字符到指定的码表中进行查询,把查到的字符编码值转成字节数存放到
OutputStreamWriter
缓冲区中。然后再调用刷新功能,或者关闭流,或者缓冲区存满后会把缓冲区中的字节数据使用字节流写到指定的文件中。

与OutputStream类一样,InputStream本身也是一个抽象类,必须依靠其子类,如果现在是从文件中读取,就用FileInputStream来实现。

3.2.InputSreamReader类

观察FileInputStream类的构造方法:

查阅 InputStreamReader 的 API 介绍, InputStreamReader
是字节流通向字符流的桥梁:它使用指定的 charset
读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

public FileInputStream(File file)throws FileNotFoundException

1publicclassInputStreamReaderDemo{2publicstaticvoidmain(String[] args)
throws
IOException{3//演示字节转字符流的转换流4readCN();5}6publicstaticvoidreadCN()
throws
IOException{7//创建读取文件的字节流对象8InputStreamin=newFileInputStream(“c:
\cn8.txt”);9//创建转换流对象 10//InputStreamReader isr = new
InputStreamReader;这样创建对象,会用本地默认码表读取,将会发生错误解码的错误11InputStreamReader
isr
=newInputStreamReader(in,”utf-8″);12//使用转换流去读字节流中的字节13intch
=0;14while((ch =
isr.read{15System.out.println;16}17//关闭流18isr.close();19}20}

读文件:

注意:在读取指定的编码的文件时,一定要指定编码格式,否则就会发生解码错误,而发生乱码现象。

3.3.转换流和子类的区别

1importjava.io.File;

发现有如下继承关系:

2importjava.io.FileInputStream;

OutputStreamWriter:

3importjava.io.IOException;

FileWriter:

4importjava.io.InputStream;

InputStreamReader:

5

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website