JavaRush /Java Blog /Random-TW /從鍵盤上閱讀——“讀者”

從鍵盤上閱讀——“讀者”

在 Random-TW 群組發布
你好!在講座和任務中,我們學習如何將資料輸出到控制台,反之亦然 - 從鍵盤讀取資料。 從鍵盤讀取 - “讀者” - 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