“又是我。”

“嗨,艾莉!”

“今天我想告诉大家有关BufferedReaderBufferedWriter 的所有信息。”

“你已经跟我说过了。它们真的没有那么复杂。”

“好的。那告诉我BufferedReader是如何工作的。”

BufferedReader就像一个 110/220V 转换器。”

“您必须将读取数据的Reader对象传递给BufferedReader构造函数。BufferedReader对象从Reader读取大块数据并将它们存储在内部缓冲区中。这就是为什么使用 BufferedReaderReader读取更快而不是直接从Reader阅读。”

“没错。那么BufferedWriter呢?”

“这是小菜一碟。假设我们写入一个FileWriter。数据会立即写入磁盘。如果我们频繁写入少量数据,那么我们会经常访问磁盘,这会大大降低程序速度。但是如果我们使用BufferedWriter作为“转换器”,那么写入操作会快得多。当您写入 BufferedWriter 时它将数据保存在内部缓冲区中。当缓冲区已满时,它将数据写入Writer为一大块。这要快得多。”

“嗯。没错。但你忘了什么?”

“完成写入后,您需要在BufferedWriter对象上调用flush()方法以强制它将仍在缓冲区中的任何数据发送到 Writer

“还有什么?”

“还有什么?哦!只要缓冲区还没有写入 Writer 就可以删除和/或替换数据。”

“阿米戈!我印象深刻!你是专家!好吧,那么我会告诉你一些新类:  ByteArrayStreamPrintStream。”

“例如,ByteArrayInputStreamByteArrayOutputStream。”

“这些类有点像StringReaderStringWriter。除了StringReader从字符串 ( String ) 中读取字符 ( char ) ,而InputStream从字节数组 ( ByteArray ) 中读取字节。”

StringWriter将字符 ( char ) 写入字符串,而ByteArrayOutputStream将字节写入内部字节数组。当您写入StringWriter时,其内部字符串会变长,而当您写入ByteArrayOutputStream时,其内部字节数组也会动态扩展。

“记住上节课给你的例子:”

从 reader 对象读取并写入 writer 对象:
public static void main (String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n";
 StringReader reader = new StringReader(test);

 StringWriter writer = new StringWriter();

 executor(reader, writer);

 String result = writer.toString();

 System.out.println("Result: "+ result);
}

public static void executor(Reader reader, Writer writer) throws Exception
{
 BufferedReader br = new BufferedReader(reader);
 String line;
 while ((line = br.readLine()) != null) {
 StringBuilder sb = new StringBuilder(line);
 String newLine = sb.reverse().toString();

 writer.write(newLine);
 }
}

“如果它使用字节而不是字符,它会是这样的:”

从 InputStream 对象读取并写入 OutputStream 对象:
public static void main (String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n";
 InputStream inputStream = new ByteArrayInputStream(test.getBytes());

 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

 executor(inputStream, outputStream);

 String result = new String(outputStream.toByteArray());
 System.out.println("Result: "+ result);
}

public static void executor(InputStream inputStream, OutputStream outputStream) throws Exception
{
 BufferedInputStream bis = new BufferedInputStream(inputStream);
 while (bis.available() > 0)
 {
  int data = bis.read();
  outputStream.write(data);
 }
}

“一切都与上面的示例相同。除了,我们用 ByteArray 替换了 String,用 InputStream 替换了 Reader,用 OutputStream 替换了 Writer。”

“仅有的两个其他步骤是将 String 转换为 ByteArray,然后再转换回来。如您所见,这很容易完成:”

将 String 转换为 ByteArray 并再次转换回来
public static void main (String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n";
 byte[] array = test.getBytes();

 String result = new String(array);
 System.out.println("Result: "+ result);
}

“要获取已添加到 ByteArrayOutputStream 的字节,请调用toByteArray () 方法。”

“啊。与 StringReader/StringWriter 的相似之处非常强,尤其是在你向我指出它们之后。谢谢你,Ellie,给了我一堂非常有趣的课。”

“这么着急去哪里?我还有个小礼物要给你,我想给你讲讲PrintStream类。”

“PrintStream?我还是第一次听说这个课程。”

“是的。特别是,如果您不考虑从学习 Java 的第一天起就一直在使用它的事实。您还记得System.out吗?好吧,System.out是系统的静态(类)变量类,它的类型是... PrintStream!这就是所有这些 print、println 等方法的来源。”

“哇。真有趣。我什至从来没有考虑过。告诉我更多。”

“很好。好吧,听好了。PrintStream 类是为可读输出而发明的。它几乎完全由 print 和 println 方法组成。看看这张表:”

方法 方法
void print(boolean b) void println(boolean b)
void print(char c) void println(char c)
void print(int c) void println(int c)
void print(long c) void println(long c)
void print(float c) void println(float c)
void print(double c) void println(double c)
void print(char[] c) void println(char[] c)
void print(String c) void println(String c)
void print(Object obj) void println(Object obj)
void println()
PrintStream format (String format, Object ... args)
PrintStream format (Locale l, String format, Object ... args)

“还有几种格式方法,因此您可以使用格式字符串输出数据。例如:”

将 String 转换为 ByteArray 并再次转换回来
String name = "Kolan";
int age = 25;
System.out.format("My name is %s. My age is %d.", name, age);
屏幕输出:
My name is Kolan. My age is 25.

“嗯,我记得。我们已经研究过String类的格式化方法了。”

“目前为止就这样了。”

“谢谢,艾莉。”