JavaRush /Java 博客 /Random-ZH /从键盘上阅读——“读者”

从键盘上阅读——“读者”

已在 Random-ZH 群组中发布
你好!在讲座和任务中,我们学习了如何将数据输出到控制台,反之亦然 - 从键盘读取数据。 从键盘读取 - “读者” - 1您甚至学会了为此使用复杂的结构:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
但我们仍然没有回答一个问题。

这是如何运作的?

事实上,任何程序通常都不是独立存在的。它可以与其他程序、系统、互联网等进行通信。我们所说的“通信”首先是指“交换数据”。即从外部接收一些数据,反之,将自己的数据发送到某处。即使在日常生活中,程序之间数据交换的例子也有很多。因此,在许多网站上,您可以使用 Facebook 或 Twitter 帐户登录,而不需要注册。在这种情况下,两个程序(例如 Twitter 和您尝试注册的网站)相互交换必要的数据,之后您会看到最终结果 - 授权成功。“流”一词经常用于描述编程中数据交换的过程。这个名字是从哪里来的?“流程”更多地与河流或溪流相关,而不是与编程相关。事实上,这并非没有道理:) 流本质上是一段移动的数据。也就是说,在编程中,沿着流“流动”的不是水,而是字节和字符形式的数据。从数据流中,我们可以接收部分数据并对其执行某些操作。还是用“水流”来比喻:你可以从河里舀水来煮汤、灭火或浇花。使用流,您可以使用任何数据源:互联网、计算机的文件系统或其他东西 - 这并不重要。流是一种通用工具。它们允许程序从任何地方接收数据(传入流)并将其发送到任何地方(传出流)。他们的任务是:将数据从一个地方获取并将其发送到另一个地方。 流分为两种类型:
  1. 传入流(Input)——用于接收数据
  2. 传出流(Output)——用于发送数据。
Java 中的传入数据流是在类中实现的InputStream,传出数据流也是在类中实现的OutputStream。但还有另一种划分线程的方法。它们不仅分为传入和传出,还分为字节字符。这里意思很清楚,不用解释:字节流以字节集合的形式传输信息,字符流以字符集合的形式传输信息。在本次讲座中,我们将详细介绍传入流。我会在最后附上有关传出链接的信息,您可以自己阅读:) 所以,我们的代码:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
您在阅读讲座时可能会觉得它看起来很可怕?:) 但这只是在我们弄清楚这个东西是如何工作之前。我们现在就解决它!让我们从最后开始吧。 是我们一开始谈到的System.in类的一个对象。InputStream这是一个传入流,它与系统输入设备 - 键盘相关联。顺便说一句,你间接地认识他。毕竟你在工作中经常会用到他的“同事”—— System.out- 这是一个系统数据输出System.out流,它用于以您经常使用的方法输出到控制台:) - 用于将数据发送到控制台的流,以及- 用于从键盘接收数据的流。这很简单:)此外:要从键盘读取数据,我们可以不需要这个大的结构,只需编写:; System.out.println()System.outSystem.inSystem.in.read()
public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
在类中InputStream(并且System.in,让我提醒您,是类的对象InputStream)有一个read()允许您读取数据的方法。一个问题:它读取字节,而不是字符。让我们尝试从键盘上读出俄语字母“Ya”。控制台输出:
Я
208
175
10
俄语字母在计算机内存中占用 2 个字节(与英语字母不同,英语字母仅占用 1 个字节)。在本例中,从流中读取了 3 个字节:前两个代表我们的字母“I”,另一个是换行符 (Enter)。因此,使用“裸”的选择System.in不适合我们。人类(除了极少数例外!)无法读取字节。这就是下一堂课来帮助我们的地方 - InputStreamReader!我们先来看看这是什么动物。
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
我们将流传System.in递给InputStreamReader. 一般来说,如果你把它的名字翻译成俄语,一切看起来都很明显——“传入流的阅读器”。事实上,这正是它的目的!我们创建一个类对象InputStreamReader并向其传递一个传入流,它应该从中读取数据。在这种情况下...
new InputStreamReader(System.in)
...我们告诉它:“您将从系统输入流(键盘)读取数据。” 但这不是它唯一的功能! InputStreamReader不仅从流中接收数据。它还将字节流转换为字符流。换句话说,您不再需要担心将读取的数据从“计算机”语言翻译成“人类”语言 -InputStreamReader它会为您完成一切。 InputStreamReader当然,不仅可以从控制台读取数据,还可以从其他地方读取数据。例如,从文件中:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

   public static void main(String[] args) throws IOException {
       InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\Users\\username\\Desktop\\testFile.txt"));
   }
}
在这里,我们创建了一个传入数据流FileInputStream(这是变体之一InputStream),将文件的路径传递到其中,并将流本身传递给InputStreamReader“y”。当然,如果该路径中的文件存在的话,现在它将能够从此文件中读取数据。为了读取数据(无论从何处、从控制台、文件或其他任何地方),该类InputStreamReader还使用read(). System.in.read()和 和有什么区别InputStreamReader.read()?让我们尝试使用 来计算同一个字母“I” InputStreamReader。让我提醒你,这就是我的想法System.in.read()
Я
208
175
10
他怎么能做同样的工作InputStreamReader呢?
public class Main {

   public static void main(String[] args) throws IOException {

       InputStreamReader reader = new InputStreamReader(System.in);
       while (true) {
           int x = reader.read();
           System.out.println(x);
       }
   }
}
控制台输出:
Я
1071
10
差异立即可见。最后一个字节(用于换行符)保持不变(数字 10),但读取的字母“I”被转换为单个代码“1071”。这就是符号阅读!如果你突然不相信代码1071代表字母“I”,你可以轻松验证这一点:)
import java.io.IOException;

public class Main {

   public static void main(String[] args) throws IOException {

       char x = 1071;
       System.out.println(x);
   }
}
控制台输出:

Я
但如果InputStreamReader它这么好,为什么还需要更多呢BufferedReaderInputStreamReader既可以读取数据,也可以将字节转换为字符——我们还需要什么?为什么还要另一个读者?:/ 答案非常简单 - 提高生产力便利性。让我们从性能开始。 读取数据时, BufferedReader使用一个特殊区域 - 缓冲区,在其中“添加”读取的字符。这样一来,当我们在程序中需要这些字符时,就会从缓冲区中取出,而不是直接从数据源(键盘、文件等)中取出,这样就节省了很多资源。要了解其工作原理,请想象一下,例如,一家大公司的快递员的工作。快递员坐在办公室里,等待包裹送到他面前。每次他收到新包裹,他就可以立即上路。但白天的包裹可能会很多,他每次都得往返于办公室和地址之间。相反,快递员在办公室里放了一个盒子,每个人都可以把包裹放在那里。现在,快递员可以平静地拿起箱子并前往地址 - 他将节省大量时间,因为他不必每次都返回办公室。这个例子中的盒子就是缓冲区,办公室就是数据源。对于快递员来说,投递信件时从普通信箱中取出信件比每次都去办公室要容易得多。它还可以节省汽油。在程序中也是一样的——从缓冲区获取数据比每次都访问数据源所占用的资源要少得多。这就是为什么BufferedReader+InputStreamReader比 仅仅运行得更快InputStreamReader。性能我们已经整理好了,那么便利性呢?主要优点是BufferedReader它不仅可以一次读取一个字符(尽管read()它也有一种用于此目的的方法),还可以读取整行!这是使用readLine(); 完成的。
public class Main {

   public static void main(String[] args) throws IOException {

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
       String s = reader.readLine();
       System.out.println("We read this line from the keyboard:");
       System.out.println(s);
   }
}
控制台输出:
JavaRush is the best site to learn Java!
Мы считали с клавиатуры эту строку:
JavaRush — лучший сайт для изучения Java!
这在读取大量数据时特别有用。一两行文本仍然可以逐个字符地阅读。但是一次计算“战争与和平”一个字母会有些问题:) 现在线程的工作对你来说已经变得更加清晰了。为了进一步研究,这里有一个额外的资源供您使用: 在这里您可以阅读有关传入和传出流量的更多信息。BufferedReader我们的一位学生的视频评论。是的,是的,我们的学生不仅自己学习,还为别人录制教育视频!不要忘记喜欢并订阅我们的频道:)
最好从学习之初就养成阅读官方文档的习惯。它是语言知识的主要来源,大多数答案都可以在那里找到。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION