CodeGym/Java 博客/随机的/练习使用 BuffreredReader 和 InputStreamReader 类
John Squirrels
第 41 级
San Francisco

练习使用 BuffreredReader 和 InputStreamReader 类

已在 随机的 群组中发布
个会员
你好!为了方便起见,今天的课程将分为两部分。我们将重复我们之前触及的一些旧主题,并且我们将考虑一些新功能 :) 让我们从第一个开始。你已经上过很多次课了BufferedReader。我希望你没有时间忘记这句话:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
在进一步阅读之前,试着记住每个组件 — System.in, InputStreamReader, BufferedReader— 负责什么以及为什么需要它。你是否记得?如果没有,不用担心。:) 如果您忘记了什么,请重新阅读本课程,该课程专供读者上课。我们将简要回顾一下他们每个人可以做什么。 System.in— 这是一个从键盘接收数据的流。 原则上,它本身就足以实现阅读文本所需的逻辑。但是,您会记得,System.in只能读取字节,不能读取字符:
public class Main {

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

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
如果我们执行这段代码并输入西里尔字母“Й”,输出将是:
Й
208
153
10
西里尔字符在内存中占2个字节,显示在屏幕上。数字 10 是换行符的十进制表示,即来自按 Enter 键。读字节是一种乐趣,所以使用起来System.in不是很方便。为了正确阅读西里尔(和其他)字母,我们使用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);
       }
   }
}
我们输入相同的字母“Й”,但这次结果不同:
Й
1049
10
InputStreamReader将两个字节(208和153)转换为单个数字1049。这就是读取字符的意思。1049对应西里尔字母“Й”。我们可以很容易地说服自己这是真的:
public class Main {

   public static void main(String[] args) throws IOException {
       char x = 1049;
       System.out.println(x);
   }
}
控制台输出:
Й
作为forBufferedReader(一般而言BufferedAnythingYouWant),缓冲类用于优化性能。访问数据源(文件、控制台、Web 资源)在性能方面非常昂贵。因此,为了减少访问次数,BufferedReader将数据读取并累积在一个专门的缓冲区中,我们从那里获取。结果,数据源被访问的次数大幅减少——可能减少了几个数量级!的另一个BufferedReader特点及其优于普通的方法InputStreamReader是非常有用的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 ("The user entered the following text:");
       System.out.println(s);
       reader.close();
   }
}
BufferedReader+InputStreamReader is faster than InputStreamReader alone
The user entered the following text:
BufferedReader+InputStreamReader is faster than InputStreamReader alone
练习使用 BuffreredReader 和 InputStreamReader 类 - 2当然BufferedReader是很灵活的。您不仅限于使用键盘。例如,您可以直接从 Web 读取数据,只需将所需的 URL 传递给读取器即可:
public class URLReader {

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

       URL oracle = new URL("https://www.oracle.com/index.html");
       BufferedReader in = new BufferedReader(
               new InputStreamReader(oracle.openStream()));

       String inputLine;
       while ((inputLine = in.readLine()) != null)
           System.out.println(inputLine);
       in.close();
   }
}
您可以通过传递文件路径从文件中读取数据:
public class Main {

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

       FileInputStream fileInputStream = new FileInputStream("testFile.txt");
       BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));

       String str;

       while ((str = reader.readLine()) != null)   {
           System.out.println (str);
       }

       reader.close();
   }
}

替换 System.out

现在让我们来看看我们以前没有接触过的一个有趣的功能。您一定记得,该类System有两个静态字段 —System.in和 System.out. 这些孪生兄弟是流对象。 System.in是一个InputStream。并且System.out 是一个PrintStream. 现在,我们将讨论 System.out. 如果我们进入System类的源代码,我们会看到:
public final class System {
……………...
public final static PrintStream out = null;
 …………
}
因此, System.out  只是该类的一个普通静态变量System。这没什么神奇的:)out变量是一个PrintStream引用。这里有一个有趣的问题:什么时候System.out.println()执行,为什么输出到控制台而不是其他地方?这可以以某种方式改变吗?例如,假设我们要从控制台读取数据并将其写入文本文件。是否有可能以某种方式简单地使用 System.out而不是额外的阅读器和编写器类来实现这一点?的确,它是 :) 即使System.out变量标有修饰符,我们也可以做到final!  练习使用 BuffreredReader 和 InputStreamReader 类 - 3那么我们需要什么来实现这一点?首先,我们需要一个新PrintStream对象来替换当前对象。当前对象,设置在System默认情况下,类不符合我们的目的:它指向控制台。您需要创建一个指向文本文件的新文件——我们数据的“目的地”。其次,我们需要了解如何为变量分配新值System.out。您不能使用简单的赋值运算符,因为变量被标记为final。 让我们从头开始倒推。碰巧的是,这个System类有我们需要的方法:setOut()。它获取一个PrintStream对象并将其设置为输出目标。这正是我们所需要的!剩下的就是创建一个PrintStream对象。这也很容易:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
完整代码如下所示:
public class SystemRedirectService {

   public static void main(String arr[]) throws FileNotFoundException
   {
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
       /* Save the current value of System.out in a separate variable so that later
       we can switch back to console output */

       PrintStream console = System.out;
       // Assign a new value to System.out
       System.setOut(filePrintStream);
       System.out.println("This line will be written to the text file");

       // Restore the old value of System.out
       System.setOut(console);
       System.out.println("But this line will be output to the console!");
   }
}
结果,第一个字符串被写入文本文件,第二个字符串显示在控制台中 :) 您可以将这段代码复制到您的 IDE 中并运行它。打开文本文件,你会看到字符串已经成功写入:) 到此,我们的课程就结束了。今天我们回顾了如何使用流和阅读器。我们回顾了它们之间的不同之处,并了解了 的一些新功能System.out,我们几乎在每一节课中都使用过这些功能 :) 直到下一节课!
评论
  • 受欢迎
你必须先登录才能发表评论
此页面还没有任何评论