Java中的输入输出流根据格式又可以分为字节流和字符流:(成对)

    字节流:FileInputStream,FileOutputStream   ;  BufferedInputStream,BufferedOutputStream  ;

    字符流:FileReader,FileWriter ; BufferedReader,BufferedWriter

字符流和字节流的主要区别:

 1.字节流读取的时候,读到一个字节就返回一个字节;(一个英文字符是一个字节);字符流使用了字节流读到一个或多个字节(一个中文是两个字节,在UTF-8码表中是3个字节,这要看编码方式,不同的编码中文是不同的大小)时。先去查指定的编码表,将查到的字符返回。

只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。

 

下面根据字节流和字符流来依次说明:

   字节流:

1.   FileInputStream,FileOutputStream(  这两个都是成对出现,前者进行输入(读文件)操作,后者进行输出(写文件)操作)

FileInputStream类称为文件输入流。它的作用是将文件中的数据输入到内存中,我们可以利用它来读文件。由于它属于字节流,因此在读取Unicode字符(如中文)的文件时可能会出现问题。

该类的构造方法:

·FileInputStream(File file):打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定。

·FileInputStream(String name):打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径名name指定。

 

这里提一下File类,File类的对象不但可以表示文件,还可以表示目录;当创建一个文件对象后,就可以利用它来对文件或目录的属性进行操作,如:文件名、最后修改日期、文件大小等等;需要注意的是,File对象并不能直接对文件进行读/写操作,只能查看文件的属性;创建格式:File file = new File("test.txt");

 

FileOutputStream类称为文件输出流,他的作用是将数据写到文件中,我们可以利用它来写文件。

该类的构造方法:

·FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流。
·FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流。

常用到的方法:

·void write(byte[] b):将b.length个字节从指定byte数组写入此文件输出流中。

 ·void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入此文件输出流。

·void write(int b):将指定字节写入此文件输出流。

 

2.  BufferedInputStream,BufferedOutputStream(这对可以和上面一组对比着看,主要就是相差了一个缓冲区)

BufferedInputStream类称为缓冲输入流,其本身带有一个缓冲区,在读取数据时,先放到缓冲区中,可以减少对数据源的访问,提高运行的效率。

构造方法:

·BufferedInputStream(InputStream in):创建一个BufferedInputStream并保存其参数,即输入流in,以便将来使用。

·BufferedInputStream(InputStream in,int size):创建一个具有指定缓冲区大小的BufferedInputStream并保存其参数,即输入流in,以便将来使用。

 常用方法:

 ·int read():从输入流中读取数据的下一个字节。

 ·int read(byte[] b,int off,int len):从此字节输入流中给定偏移量处开始将各字节读取到指定的byte数组中。

 

BufferedOutputStream类称为缓冲输出流,其本身也带有一个缓冲区,在写入数据时,先放到缓冲区中,实现缓冲的数据流。要注意在使用BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。否则可能无法写出数据。

构造方法:

·BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流,来将数据写入指定的底层输入流。
 ·BufferedOutputStream(OutputStream out,int size):创建一个新的缓冲输出流,来将具有指定缓冲区大小的数据写入指定的底层输出流。

 常用方法:

·void flush():刷新此缓冲的输出流。

·void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入此缓冲的输出流。

 ·void write(int b):将指定的字节写入此缓冲的输出流。

 

  字符流:

FileReader,FileWriter ; BufferedReader,BufferedWriter(放在一起说)

FileReader类称为文件读取流,允许以字符流的形式对文件进行读操作(该类将从文件中逐个地读取字符,效率比较低下,因此一般将该类对象包装到缓冲流中进行操作。BufferedReader类主要为字符流提供缓冲,所以FileReader一般配合BufferReader来用)

构造方法:

FileReader(String fileName) FileReader(File file)常用方法://都是继承自Reader的方法 int read() int read(char[] b) int read(char[] b , int off ,int len)

FileWriter类称为文件写入流,以字符流的形式对文件进行写操作与FileReader类相似,FileWriter类同样需要使用缓冲流进行包装,所以FileWriter一般配BufferedWriter来用  

构造方法:FileWriter(String fileName)FileWriter(String fileName, boolean append) //boolean append是否在原有基础上继续写FileWriter(File file)FileWriter(File file, boolean append)//boolean append是否在原有基础上继续写

常用方法:

void write(char[] b)void write(char[] b, int off, int len)void write(int b)void write(String str)void write(String str, int off, int len)Writer append(char c)Writer append(CharSequence csq)Writer append(CharSequence csq, int start, int end)

为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率。BufferedReader用于加快读取字符的速度,BufferedWriter用于加快写入的速度。BufferedReader和BufferedWriter类各拥有8192个字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并放满缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。

 

BufferedReader是为了提供读的效率而设计的一个包装类,它可以包装字符流。可以从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

构造方法:

BufferedReader(Reader in)      //创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz)  //创建一个使用指定大小输入缓冲区的缓冲字符输入流。

常用方法:

int read()                 //读取单个字符。
int read(char[] cbuf, int off, int len)  //将字符读入数组的某一部分。
String readLine()             //读取一个文本行。(不包括换行符)

BufferedWriter:

构造方法:

BufferedWriter(Writer out)      //创建一个缓冲字符输出流,使用默认大小的输出缓冲区
BufferedWriter(Writer out, int sz)  //创建一个缓冲字符输出流,使用给定大小的输出缓冲区

常用方法:

void write(int c)             //写入单个字符。
void write(char[] cbuf, int off, int len) //写入字符数组的某一部分。
void write(String s, int off, int len)   //写入字符串的某一部分。
void newLine()               //写入一个行分隔符。
void close()                //关闭此流,但要先刷新它
void flush()                //刷新该流的缓冲

 

乱码问题:

处理纯文本数据,就要优先考虑使用字符流,但是考虑到编码的因素,可以使用包装InputStreamReader的BufferedReader,包装OutputStreamWriter的BufferedWriter来复制文件,好处就是可以指定复制文件的时候使用的字符编码使不产生乱码。下面讲一下InputStreamReader和OutputStreamWriter:

InputStreamReader:它使用指定的字符集读取字节并将它们解码为字符。 它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。每次调用一个InputStreamReader的read()方法都可能导致从底层字节输入流中读取一个或多个字节。为了获得最高效率,通常在BufferedReader中包装InputStreamReader。

使用格式: BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile),"UTF-8"));
BufferedReader

OutputStreamWriter:它使用指定的字符集将字符编码为字节(是InputStreamReader的逆过程)。它的字符集可以由名称指定,也可以接受平台的默认字符集。

使用格式:

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(destFile), "UTF-8"))