关于 Java 的 I/O 类 的问题
Questions on Java's I/O Classes
我正在阅读 java 中有关网络的教程 (client/server),我有一个我不明白的问题。
https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
我经常看到这个
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
和
BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
我知道 BufferReader 的构造函数是
BufferedReader(Reader in)
1) 我还知道,由于 InputStreamReader 是由 Reader class 继承的,因此您可以通过 BufferedReader 构造函数传递它。但我的问题是为什么我们需要 InputStreamReader?是因为 InputStreamReader 可以容纳一个输入流(根据它在 API 中的构造函数)
编辑:我有误,请忽略
2) 现在对于下一部分,inputStream & outputStream(根据API)是从Object class继承的。这两个 classes 如何分别分配为 BufferedReader 和 PrintWriter。这是因为它们都被对象class继承了,还是另有原因?因为如果是这样的话,怎么会有人知道你可以分配什么 class 就好像一切都应该由对象 class 继承一样。
3) 最后但同样重要的是,这里还有一个关于 BufferedReader 和 PrintWriter 的问题
BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
为什么这两个 classes 选择通过 FileReader 和 FileWriter classes 的引用?
我想我想了解更多关于为什么选择这些特定 classes 的信息。
提前致谢!
1) 要构造BufferedReader
,您需要一个Reader
参数。 System.in
不是 Reader
。 Java IO 拼图的每个部分只做一件事:InputStreamReader
从 InputStream
得到一个 Reader
,然后 BufferedReader
缓冲 Reader
.
2) 他们不能,正是因为#1。首先将 InputStream
包装在 Reader
或 Writer
包装器中,然后您可以做其他事情。
3) 因为他们正在读取/写入文件,而不是流。 (编辑:并且,正如评论中提到的 pvg,inputStream = new BufferedReader(...)
和 outputStream = new PrintWriter(...)
是极其混乱的变量名称。)
基本上,它就像一个制造。你有 System.in
,这是一个 InputStream
。这意味着他给你的是纯字节。您不需要纯字节;您希望获得字符(即由某些字符编码解析的字节,例如 UTF-8)。但是 InputStream
不知道该怎么做。
输入InputStreamReader
。作为每个Reader
,他知道如何给你角色。具体来说 InputStreamReader
知道如何从 InputStream
中获取字节并将其作为字符传递。所以你把他排在System.in
前面,这样你就不用对付他了。
但您不想一次获取每个字符。你想要更多。您希望能够一次阅读整行!你想要……缓冲!输入 BufferedReader
:他是站在另一个 Reader
前面的人,收集每个角色并把它扔掉,直到你要一些。
要了解到底发生了什么,您需要了解基于字节的 IO 和基于文本的 IO 之间的关键区别,并研究每个 class' 的构造函数以了解它究竟是什么样的东西包装(尽管名称是一个很好的提示)。
好的,原因很简单
这是装饰器设计模式。
你拿一个基本的 object 并继续在它上面添加所需的装饰。
示例:有 2 种浇头的披萨(我现在很饿)
你这样做是因为它减少了所需的不同 classes 的数量(InputStreamReader * Buffered/UnBuffered * bla bla bla 导致许多不同的组合,所以如果我们有一个 child class 对于每个组合,它将是 100+ stream classes 我们会感到困惑,所以我们简单地装饰它(所有类型都有相同的接口,我们在构造函数中相互传递)
如果仍有疑问,请 google 装饰器模式了解详情
我正在阅读 java 中有关网络的教程 (client/server),我有一个我不明白的问题。
https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
我经常看到这个
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
和
BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
我知道 BufferReader 的构造函数是
BufferedReader(Reader in)
1) 我还知道,由于 InputStreamReader 是由 Reader class 继承的,因此您可以通过 BufferedReader 构造函数传递它。但我的问题是为什么我们需要 InputStreamReader?是因为 InputStreamReader 可以容纳一个输入流(根据它在 API 中的构造函数)
编辑:我有误,请忽略
3) 最后但同样重要的是,这里还有一个关于 BufferedReader 和 PrintWriter 的问题
BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
为什么这两个 classes 选择通过 FileReader 和 FileWriter classes 的引用?
我想我想了解更多关于为什么选择这些特定 classes 的信息。
提前致谢!
1) 要构造BufferedReader
,您需要一个Reader
参数。 System.in
不是 Reader
。 Java IO 拼图的每个部分只做一件事:InputStreamReader
从 InputStream
得到一个 Reader
,然后 BufferedReader
缓冲 Reader
.
2) 他们不能,正是因为#1。首先将 InputStream
包装在 Reader
或 Writer
包装器中,然后您可以做其他事情。
3) 因为他们正在读取/写入文件,而不是流。 (编辑:并且,正如评论中提到的 pvg,inputStream = new BufferedReader(...)
和 outputStream = new PrintWriter(...)
是极其混乱的变量名称。)
基本上,它就像一个制造。你有 System.in
,这是一个 InputStream
。这意味着他给你的是纯字节。您不需要纯字节;您希望获得字符(即由某些字符编码解析的字节,例如 UTF-8)。但是 InputStream
不知道该怎么做。
输入InputStreamReader
。作为每个Reader
,他知道如何给你角色。具体来说 InputStreamReader
知道如何从 InputStream
中获取字节并将其作为字符传递。所以你把他排在System.in
前面,这样你就不用对付他了。
但您不想一次获取每个字符。你想要更多。您希望能够一次阅读整行!你想要……缓冲!输入 BufferedReader
:他是站在另一个 Reader
前面的人,收集每个角色并把它扔掉,直到你要一些。
要了解到底发生了什么,您需要了解基于字节的 IO 和基于文本的 IO 之间的关键区别,并研究每个 class' 的构造函数以了解它究竟是什么样的东西包装(尽管名称是一个很好的提示)。
好的,原因很简单
这是装饰器设计模式。 你拿一个基本的 object 并继续在它上面添加所需的装饰。 示例:有 2 种浇头的披萨(我现在很饿)
你这样做是因为它减少了所需的不同 classes 的数量(InputStreamReader * Buffered/UnBuffered * bla bla bla 导致许多不同的组合,所以如果我们有一个 child class 对于每个组合,它将是 100+ stream classes 我们会感到困惑,所以我们简单地装饰它(所有类型都有相同的接口,我们在构造函数中相互传递)
如果仍有疑问,请 google 装饰器模式了解详情