我正在用Java阅读有关网络(客户端/服务器)的本教程,并且对我不了解的问题有疑问。
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类继承,因此您可以通过BufferedReader构造函数传递它。但是我的问题是为什么我们需要InputStreamReader?是因为InputStreamReader可以保存输入流(根据API中的构造函数)
编辑:我犯了错误,请忽略此
2)现在,对于下一部分,inputStream和outputStream(根据API)从Object类继承。这两个类如何分别分配为BufferedReader和PrintWriter。这是因为它们都被对象类继承,还是另一个原因?因为如果是这种情况,那么任何人都将如何知道您可以分配给什么类,就好像一切都应该由Objects类继承一样。
3)最后但并非最不重要的一点是关于BufferedReader和PrintWriter的另一个问题
BufferedReader inputStream = new BufferedReader(new FileReader("xanadu.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
为什么这两个类选择通过FileReader和FileWriter类的引用?
我想我想要更多有关为什么选择这些特定类的信息。
提前致谢!
最佳答案
1)要构造BufferedReader
,您需要一个Reader
参数。 System.in
不是Reader
。 Java IO难题的每个部分都只做一件事:InputStreamReader
从Reader
为您提供InputStream
,然后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之间的关键区别,并研究每个类的构造函数以确切查看其包装的是哪种东西(尽管名称是一个很好的提示) 。
关于java - 有关Java I/O类的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31377651/