你好!在講座和任務中,我們學習如何將資料輸出到控制台,反之亦然 - 從鍵盤讀取資料。 您甚至學會了為此使用複雜的結構:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
但我們仍然沒有回答一個問題。
這是如何運作的?
事實上,任何程式通常都不是獨立存在的。它可以與其他程式、系統、網際網路等進行通訊。我們所說的「通信」首先是指「交換資料」。即從外部接收一些數據,反之,將自己的數據送到某處。即使在日常生活中,程式之間的資料交換例子也有很多。因此,在許多網站上,您可以使用 Facebook 或 Twitter 帳戶登錄,而不需要註冊。在這種情況下,兩個程式(例如 Twitter 和您嘗試註冊的網站)會相互交換必要的數據,之後您會看到最終結果 - 授權成功。「流」一詞常用來描述程式設計中資料交換的過程。這個名字是從哪裡來的?「流程」與河流或溪流有關,而不是與程式設計相關。事實上,這並非沒有道理:) 流本質上是一段移動的資料。也就是說,在程式設計中,沿著流「流動」的不是水,而是位元組和字元形式的資料。從資料流中,我們可以接收部分資料並對其執行某些操作。還是用「水流」來比喻:你可以從河裡舀水來煮湯、滅火或澆花。使用流,您可以使用任何資料來源:互聯網、電腦的檔案系統或其他東西 - 這並不重要。流是一種通用工具。它們允許程式從任何地方接收資料(傳入流)並將其發送到任何地方(傳出流)。他們的任務是:將資料從一個地方獲取並將其發送到另一個地方。 流分為兩種類型:- 傳入流(Input)-用於接收資料
- 傳出流(Output)-用於發送資料。
InputStream
,傳出資料流也是在類別中實現的OutputStream
。但還有另一種劃分線程的方法。它們不僅分為傳入和傳出,還分為位元組和字元。這裡意思很清楚,不用解釋:位元組流以位元組集合的形式傳送訊息,字元流以字元集合的形式傳送訊息。在本次講座中,我們將詳細介紹傳入流。我會在最後附上有關傳出連結的信息,您可以自己閱讀:) 所以,我們的程式碼:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
您在閱讀講座時可能會覺得它看起來很可怕?:) 但這只是在我們弄清楚這個東西是如何運作之前。我們現在就解決它!讓我們從最後開始。 是我們一開始談到的System.in
類別的一個物件。InputStream
這是一個傳入流,它與系統輸入設備 - 鍵盤相關聯。順便說一句,你間接認識他。畢竟你在工作上常常會用到他的「同事」—— System.out
!- 這是一個系統資料輸出System.out
流,它用於以您經常使用的方法輸出到控制台:) - 用於將資料發送到控制台的流,以及- 用於從鍵盤接收資料的流。這很簡單:)此外:要從鍵盤讀取數據,我們可以不需要這個大的結構,只需編寫:; System.out.println()
System.out
System.in
System.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
它這麼好,為什麼還需要更多BufferedReader
?InputStreamReader
既可以讀取數據,也可以將位元組轉換為字元——我們還需要什麼?為什麼還要另一個讀者?:/ 答案非常簡單 - 提高生產力和便利性。讓我們從性能開始。 讀取資料時, 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
我們的一位學生的影片評論。是的,是的,我們的學生不僅自己學習,還為別人錄製教育影片!不要忘記喜歡並訂閱我們的頻道:)
- BufferedReader/InputStreamReader - JavaRush 講座之一,
BufferedReader
致力於InputStreamReader
- 類別 InputStreamReader
- Class BufferedReader - 有關類別
BufferedReader
和InputStreamReader
.
GO TO FULL VERSION