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,我们几乎在每一节课中都使用过这些功能 :) 直到下一节课!
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION