JavaIO BufferedReader和BufferedWriter/PrintWriter PrintWriter和BufferedWriter的区别 PrintStream和PrintWriter的区别 PrintWriter中write与println方法的区别

为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率。BufferedReader用于加快读取字符的速度,BufferedWriter用于加快写入的速度

怎样读写:(出处:Java中,BufferedReader类的介绍及作用)

BufferedReader和BufferedWriter类各拥有8192字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。

BufferedReader

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

BufferedReader的API

1.构造函数:

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

2.方法摘要:

 int read() 
          读取单个字符。 
 int read(char[] cbuf, int off, int len) 
          将字符读入数组的某一部分。
 String readLine() 
          读取一个文本行。
 long skip(long n) 
          跳过字符。 
  boolean ready() 
          判断此流是否已准备好被读取。
void close() 
          关闭该流并释放与之关联的所有资源。 
 void mark(int readAheadLimit) 
          标记流中的当前位置。 
 boolean markSupported() 
          判断此流是否支持 mark() 操作(它一定支持)。
 void reset() 
          将流重置到最新的标记。 

实例方法:

(1)读取文件-----读取单个字符

public static void printByFileReader(String filePath) throws IOException
{
    BufferedReader reader=new BufferedReader(
            new FileReader(filePath)
            );
    if(!reader.ready())
    {
        System.out.println("文件流暂时无法读取");
        return;
    }
    int result=0;
    while((result=reader.read())!=-1)
    {
        System.out.print((char)result);
    }
    reader.close();
}

(2)读取文件-----读取一批批字符

public static void printByFileReaderChars(String filePath) throws IOException
{
	BufferedReader reader=new BufferedReader(
			new FileReader(filePath)
			);
	if(!reader.ready())
	{
		System.out.println("文件流暂时无法读取");
		return;
	}
	int size=0;
	char[] cbuf=new char[20];
	while((size=reader.read(cbuf, 0, cbuf.length))!=-1)
	{
		System.out.print(new String(cbuf,0,size));
	}
	reader.close();
}
(3)读取文件------一次读取一行字符(返回字符串,如果读到文件末尾了返回null)


public static void printByFileReaderLine(String filePath) throws IOException
{
	BufferedReader reader=new BufferedReader(
			new FileReader(filePath)
			);
	if(!reader.ready())
	{
		System.out.println("文件流暂时无法读取");
		return;
	}
	int size=0;
	String line;
	while((line=reader.readLine())!=null)
	{
		System.out.print(line+"\n");
	}
	reader.close();
}

BufferedReader比FileReader高级的地方在于这个,FileReader能一次读取一个字符,或者一个字符数组。BufferedReader也可以,同时BufferedReader还能一次读取一行字符串。

但是FileReader使用项目的编码来读取解析字符,不能指定编码,可能会出现编码问题,如果要指定编码可以使用包装InputStreamReader的BufferedReader。这样效率高,同时支持编码指定。

测试上述方法:

public static void main(String[] args) throws FileNotFoundException, IOException
{
    String packagePath=FilePath.getSrcPackagePath(TestBufferedReader.class);
    String fileutf8="testBufferedReaderUtf8.txt";
    String filegbk="testBufferedReaderGbk.txt";
    printByFileReader(packagePath+fileutf8);
    System.out.println("\n---------------------------------------");
    printByFileReader(packagePath+filegbk);
    System.out.println("\n---------------------------------------");
    printByFileReaderChars(packagePath+filegbk);
    System.out.println("\n---------------------------------------");
    printByFileReaderLine(packagePath+filegbk);
}

运行结果:

闈欏鎬?
浣滆?咃細鏉庣櫧
搴婂墠鏄庢湀鍏夛紝鐤戞槸鍦颁笂闇溿??
涓惧ご鏈涙槑鏈堬紝浣庡ご鎬濇晠涔°??
---------------------------------------
静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
---------------------------------------
静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
---------------------------------------
静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。

可以看到包装InputStreamReader的BufferedReader读取文件时候可能会出现乱码问题。

BufferedWriter的API:

1.构造函数:
BufferedWriter(Writer out) 
          创建一个缓冲字符输出流,使用默认大小的输出缓冲区
BufferedWriter(Writer out, int sz) 
          创建一个缓冲字符输出流,使用给定大小的输出缓冲区

2.方法摘要:

 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() 
          刷新该流的缓冲。 

实例:使用BufferReader和BufferWriter来复制文本文件

(1)按字符复制

static void copyByChar(String srcFile, String destFile) throws IOException
{
	BufferedReader reader = new BufferedReader(new FileReader(srcFile));
	BufferedWriter writer = new BufferedWriter(new FileWriter(destFile));
	int result=0;
	// BufferedReader读取一行的时候不读入换行符
	while ((result = reader.read()) != -1)
	{
		writer.write(result);
	}
	reader.close();
	writer.close();
}

(2)按字符数组复制

static void copyByChars(String srcFile, String destFile) throws IOException
{
	BufferedReader reader = new BufferedReader(new FileReader(srcFile));
	BufferedWriter writer = new BufferedWriter(new FileWriter(destFile));
	int size=0;
	char[] cbuf=new char[20];
	while ((size = reader.read(cbuf)) != -1)
	{
		writer.write(cbuf,0,size);
	}
	reader.close();
	writer.close();
}

(3)按行复制---readLine()和writer(String)

static void copyByLine(String srcFile,String destFile) throws IOException
{
    BufferedReader reader=new BufferedReader(new FileReader(srcFile));
    BufferedWriter writer=new BufferedWriter(new FileWriter(destFile));
    String line;
    //BufferedReader读取一行的时候不读入换行符
    while((line=reader.readLine())!=null)
    {
        writer.write(line);
        writer.newLine();//写换行符
    }
    reader.close();
    writer.close();
}

这个方法可以一行行的复制文件,使用了缓冲区,以提高读取效率。但是由于包装的是FileReader和FileWriter。有可能出现乱码问题,测试:

public static void main(String[] args) throws IOException
{
	String packagePath=FilePath.getSrcPackagePath(CopyBufferedReaderWriter.class);
	String srcFile =packagePath+"testBufferedReaderGbk.txt";
	String destFile=packagePath+"testBufferedReaderGbk副本.txt";
	String srcFileUTF8 =packagePath+"testBufferedReaderUtf8.txt";
	String destFile2=packagePath+"testBufferedReaderUtf8副本.txt";
	copyByLine(srcFile,destFile);
	copyByLine(srcFileUTF8,destFile2);
	
}

源文件testBufferedReaderUtf8.txttestBufferedReaderGbk.txt 中的内容:

静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。

运行结果

testBufferedReaderGbk副本.txt:

静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。

testBufferedReaderUtf8副本.txt:

静夜�?
作�?�:李白
床前明月光,疑是地上霜�??
举头望明月,低头思故乡�??

可以看见,出现了乱码。

整体测试:

public static void main(String[] args) throws IOException
{
	String packagePath = FilePath
			.getSrcPackagePath(CopyBufferedReaderWriter.class);
	String srcFile = packagePath + "testBufferedReaderGbk.txt";
	String destFile1 = packagePath + "testBufferedReaderGbk副本1.txt";
	String destFile2 = packagePath + "testBufferedReaderGbk副本2.txt";
	String destFile3 = packagePath + "testBufferedReaderGbk副本3.txt";
	copyByChar(srcFile, destFile1);
	copyByChars(srcFile, destFile2);
	copyByLine(srcFile, destFile3);
} 

运行结果:

testBufferedReaderGbk副本1.txt和testBufferedReaderGbk副本2.txt

静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。

testBufferedReaderGbk副本3.txt:

静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
 

可以看到按行复制复制的文件会比源文件写了一个回车符。

PrintWriter类--向文本输出流打印格式化表示形式

PintWriter是一种过滤流,也叫处理流。使用PrintWriter能方便的打印各种数据的表示形式。

PrintWriter有一系列的print方法和println方法,可以写入基本类型(转换为字符串)、字符串和对象(使用toString方法)。这些打印方法可以保证数值的表现形式不变。写的是什么样子,目的地就是什么样子。同时PrintWriter有缓冲区功能,需要及时关闭或者flush().

PrintWriter和BufferedWriter的区别

PrintWriter相对于BufferedWriter的好处在于,如果PrintWriter开启了自动刷新,那么当PrintWriter调用println,prinlf或format方法时,输出流中的数据就会自动刷新出去。PrintWriter不但能接收字符流,也能接收字节流。


PrintWriter的print、println方法可以接受任意类型的参数,而BufferedWriter的write方法只能接受字符、字符数组和字符串;

PrintWriter的println方法自动添加换行,BufferedWriter需要显示调用newLine方法;

PrintWriter的方法不会抛异常,若关心异常,需要调用checkError方法看是否有异常发生;

PrintWriter构造方法可指定参数,实现自动刷新缓存(autoflush);

PrintWriter的构造方法更广。

PrintWriter和BufferedWriter都是继承java.io.Writer,所以很多功能都一样。不过PrintWriter提供println()方法可以写不同平台的换行符,而BufferedWriter可以任意设定缓冲大小。不过PrintWriter的底层还是由BufferedWriter、BufferedStreamWriter实现的。

注意:

(1)PrintWriter只有输出写入功能,而没有读取功能



顺带比较一下

PrintStream和PrintWriter的区别
首先PrintWriter 是字符输出,PrintStream 是字符输出

PrintStream和PrintWriter的API几乎相同,都能输出各种形式的数据,构造方法也几乎相同

区别:

1.PrintStream能做的PrintWriter也都能实现,并且PrintWriter的功能更为强大。但是由于PrintWriter出现的比较晚,较早的System.out使用的是PrintStream来实现的,所以为了兼容就没有废弃PrintStream。

2.两个个类最大的差别是,PrintStream在输出字符,将字符转换为字节时采用的是系统默认的编码格式,这样当数据传输另一个平台,而另一个平台使用另外一个编码格式解码时就会出现问题,存在不可控因素。而PrintWriter可以在传入Writer时可由程序员指定字符转换为字节时的编码格式,这样兼容性和可控性会更好。


1.构造函数:

PrintWriter(File file) 
          创建PrintWriter,不自动行刷新 
PrintWriter(File file, String csn) 
          创建PrintWriter,使用指定文件file和字符集csn,不自动刷行
PrintWriter(OutputStream out) 
         以OutputStream创建PrintWriter,不自动行刷新 。 
PrintWriter(OutputStream out, boolean autoFlush) 
          以OutputStream 创建新的 PrintWriter。autoFlush为true的话自动刷新
PrintWriter(String fileName) 
          以指定文件名称创建 PrintWriter。不自动行刷新
PrintWriter(String fileName, String csn) 
          以指定文件名称和字符集创建且不带PrintWriter,不自动刷新
PrintWriter(Writer out) 
          创建PrintWriter,不自动行刷新
PrintWriter(Writer out, boolean autoFlush) 
          创建新 PrintWriter 如果autoFlush为true则自动刷新

2.格式化打印方法:

1.print()方法:打印基本数据类型(byte类型没有),打印对象,打印字符串

 void print(int i) 打印整数。
 void print(long l) 打印 long 整数
 void print(float f) 打印一个浮点数。
 void print(double d) 打印 double 精度浮点数。  
 void print(char c) 打印字符。 
 void print(char[] s) 打印字符数组。 
 void print(boolean b) 打印 boolean 值。  
 void print(Object obj) 打印对象。 
 void print(String s) 打印字符串

2.printf()方法

 PrintWriter printf(Locale l, String format, Object... args) 
          使用指定格式字符串和参数将格式化的字符串写入此 writer 的便捷方法。 
 PrintWriter printf(String format, Object... args) 
          使用指定格式字符串和参数将格式化的字符串写入此 writer 的便捷

3.println()方法 

 void println() 通过写入行分隔符字符串终止当前行。
 void println(int x) 打印整数,然后终止该行。 
 void println(long x) 打印 long 整数,然后终止该行。
 void println(char x) 打印字符,然后终止该行。 
 void println(char[] x) 打印字符数组,然后终止该行。 
 void println(float x) 打印浮点数,然后终止该行。
 void println(double x)  打印双精度浮点数,然后终止该行。 
 void println(boolean x) 打印 boolean 值,然后终止该行。 
 void println(Object x) 打印 Object,然后终止该行。 
 void println(String x) 打印 String,然后终止该行。 

4.write方法

 void write(char[] buf) 写入字符数组。 
 void write(char[] buf, int off, int len) 写入字符数组的某一部分。 
 void write(int c) 写入单个字符。 
 void write(String s) 写入字符串。 
 void write(String s, int off, int len) 写入字符串的某一部分。 

5.format()方法

PrintWriter format(Locale l, String format, Object... args) 
          使用指定格式字符串和参数将一个格式化字符串写入此 writer 中。 
 PrintWriter format(String format, Object... args) 
          使用指定格式字符串和参数将一个格式化字符串写入此 writer 中。 

6.append()方法

PrintWriter append(char c) 
          将指定字符添加到此 writer。 
 PrintWriter append(CharSequence csq) 
          将指定的字符序列添加到此 writer。 
 PrintWriter append(CharSequence csq, int start, int end) 
          将指定字符序列的子序列添加到此 writer 

7. 错误方法

boolean checkError() 
          如果流没有关闭,则刷新流且检查其错误状态。 
protected  void clearError() 
          清除此流的错误状态。 
protected  void setError() 
          指示已发生错误。

8.关闭刷新方法

 void close() 
          关闭该流并释放与之关联的所有系统资源。 
 void flush() 
          刷新该流的缓冲。 

这里有好多个写方法,来比较一下区别:

PrintWriter中write与println方法的区别

共同点:两者都不刷新页面,只在原来的页面写数据.最终都是重写了抽象类Writer里面的write方法.

print方法可以将各种类型的数据转换成字符串的形式输出。重载的write方法只能输出字符、字符数组、字符串等与字符相关的数据。

write()方法不会写入换行符,如果用write()在一端写入了信息,在另一端如果用readLine()方法。由于读不到换行符,意味中读不到结束标记,然后由于IO流是阻塞式的,所以程序就是一直卡在那里不动了。原因即为缺少回车标识。如果在写入的时候加上“\r\n”,就可以解决这个问题了。而println()就自动加上了换行符了。

OutputStreamWriter、PrintWriter和BufferedWriter区别

PrintWriter无追加模式,若写入已有文件,将清空原文件,重新写入;其println自动换行;
OutputStreamWriter与BufferedWriter有追加模式,append设置为true时,在已有文件末尾追加;append=false时,从已有文件第一行开始覆盖写入, 若写入内容比原有文件短,则只覆盖部分内容
BufferedWriter需手动换行,bw.newLine();
OutputStreamWriter和BufferedWriter的缺省buffersize,OutputStreamWriter是8k bytes,BufferedWriter是8k chars。

OutputStreamWriter,PrintWriter能控制编码,BufferedWriter不能。

BufferedWriter封装的是writer,也就是当buffer满了让别的writer去处理输出。而OutputStreamWriter封装的事数据流(OutputStream),它是让数据流去处理输出。stream和writer的不同不用说,一个是二进制数据,一个是字符数据,这两个根本就不一样了。

实例:使用BufferReader和PrintWriter复制文本文件

public static void copy(String srcPath,String destPath) throws IOException
{
    BufferedReader reader=new BufferedReader(
            new FileReader(srcPath)
            );
    //不带自动刷新的字符打印流
    PrintWriter writer=new PrintWriter(destPath);
    String line;
    while((line=reader.readLine())!=null)
    {
        writer.println(line);
        writer.flush();//手动刷新
    }
    reader.close();
    writer.close();
}

测试:

public static void main(String[] args) throws IOException
{
    String packagePath=FilePath.getSrcPackagePath(TestPrintWriter.class);
    String srcFile=packagePath+"fileGbk.txt";
    String destFile=packagePath+"副本.txt";
    copy(srcFile,destFile);
}

fileGbk.txt:

静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。

运行后:副本.txt

静夜思
作者:李白
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
使用PrintWriter来写文本文件十分的简介方便。平时使用时可考虑BufferReader和PrintWriter搭配使用。

参考:

PrintWriter中write与println方法的区别

PrintWriter和BufferedWriter的使用区别

OutputStreamWriter、PrintWriter和BufferedWriter区别





猜你喜欢

转载自blog.csdn.net/qq_21808961/article/details/80330113