Java.io包幾乎包含了所有操作輸入、輸出需要的類。所有這些流類代表了輸入源和輸出目標。
Java.io包中的流支援很多種格式,比如:基本類型、對象、本地化字元集等等。
一個流可以理解為一個資料的序列。輸入資料流表示從一個源讀取資料,輸出資料流表示向一個目標寫資料。
讀取控制台輸入
Java的控制台輸入由System.in完成。
為了獲得一個綁定到控制台的字元流,你可以把System.in封裝在一個BufferedReader對象中來建立一個字元流。
下面是建立BufferedReader的基本文法:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader對象建立後,我們便可以使用read()方法從控制台讀取一個字元,或者用readLine()方法讀取一個字串。
從控制台讀取多字元輸入
從BufferedReader對象讀取一個字元要使用read()方法,它的文法如下:
int read() throws IOException
每次調用read()方法,它從輸入資料流讀取一個字元並把字元作為整數值返回。當流結束的時候返回-1。該方法拋出IOException。
下面的程式示範了用read()方法從控制台不斷讀取字元直到使用者輸入“q”。
import java.io.*;public class BRRead { public static void main(String args[]) throws IOException { char c; //使用System.in建立BufferedReader BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); System.out.println("輸入字元,按下'q'鍵退出。"); //讀取字元 do { c=(char)br.read(); System.out.println(c); }while(c!='q'); }}
輸出結果:
輸入字元,按下'q'鍵退出。123q456123q
從控制台讀取字串
從標準輸入讀取一個字串需要使用BufferedReader的readLine()方法。
它的一般格式是:
String readLine() throws IOException
下面的程式讀取和顯示字元行直到你輸入了單詞”end”。
import java.io.*;public class BRReadLines { public static void main(String[] args) throws IOException { //使用System.in建立BufferedReader BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in)); String str; System.out.println("Enter lines of text."); System.out.println("Enter 'end' to quit."); do { str=bufferedReader.readLine(); System.out.println(str); }while(!str.equals("end")); }}
運行結果:
Enter lines of text.Enter 'end' to quit.oneonetwotwoendend
JDK 5後的版本我們也可以使用Java Scanner類來擷取控制台的輸入。
Java.util.Scanner是Java5的新特徵,我們可以通過Scanner類來擷取使用者的輸入。
下面是建立Scanner對象的基本文法:
Scanner s = new Scanner(System.in);
接下來我們示範一個最簡單的資料輸入,並通過Scanner類的next()與nextLine()方法擷取輸入的字串,在讀取前我們一般需要使用hasNext與hasNextLine判斷是否還有輸入的資料:
使用next方法:
import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 從鍵盤接收資料 // next方式接收字串 System.out.println("next方式接收:"); // 判斷是否還有輸入 if (scan.hasNext()) { String str1 = scan.next(); System.out.println("輸入的資料為:" + str1); } scan.close(); }}
運行結果:
next方式接收:runoob com輸入的資料為:runoob
可以看到com字串並未輸出,接下來我們看nextLine。
使用nextLine方法:
import java.util.Scanner;public class ScannerDemo { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 從鍵盤接收資料 // nextLine方式接收字串 System.out.println("nextLine方式接收:"); // 判斷是否還有輸入 if (scan.hasNextLine()) { String str2 = scan.nextLine(); System.out.println("輸入的資料為:" + str2); } scan.close(); }}
運行結果:
nextLine方式接收:runoob com輸入的資料為:runoob com
可以看到com字串輸出。
next()與nextLine()區別
next(): 一定要讀取到有效字元後才可以結束輸入。 對輸入有效字元之前遇到的空白,next()方法會自動將其去掉。 只有輸入有效字元後才能將其後面的空白作為分隔字元或者結束符。 next()不能得到帶有空格的字串。
nextLine(): 以Enter為結束符,也就是說nextLine()方法返回的是輸入斷行符號之前的所有字元。 可以獲得空白。
如果要輸入int或float類型的資料,在Scanner類中也有支援,但是在輸入之前最好先使用hasNextXxx()方法進行驗證,再使用nextXxx()來讀取:
import java.util.Scanner;public class ScannerDemo { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 從鍵盤接收資料 int i = 0; float f = 0.0f; System.out.print("輸入整數:"); if (scan.hasNextInt()) { // 判斷輸入的是否是整數 i = scan.nextInt(); // 接收整數 System.out.println("整數資料:" + i); } else { // 輸入錯誤的資訊 System.out.println("輸入的不是整數。"); } System.out.print("輸入小數:"); if (scan.hasNextFloat()) { // 判斷輸入的是否是小數 f = scan.nextFloat(); // 接收小數 System.out.println("小數資料:" + f); } else { // 輸入錯誤的資訊 System.out.println("輸入的不是小數。"); } scan.close(); }}
運行結果:
輸入整數:10整數資料:10輸入小數:12.2小數資料:12.2
以下執行個體我們可以輸入多個數字,並求其總和與平均數,每輸入一個數字用斷行符號確認,通過輸入非數字來結束輸入並輸出執行結果:
import java.util.Scanner;class ScannerDemo { public static void main(String[] args) { Scanner scan = new Scanner(System.in); double sum = 0; int m = 0; while (scan.hasNextDouble()) { double x = scan.nextDouble(); m = m + 1; sum = sum + x; } System.out.println(m + "個數的和為" + sum); System.out.println(m + "個數的平均值是" + (sum / m)); scan.close(); }}
運行結果:
1234t4個數的和為10.04個數的平均值是2.5
輸入的時候字元都是可見的,所以Scanner類不適合從控制台讀取密碼。從Java SE 6開始特別引入了Console類來實現這個目的。若要讀取一個密碼,可以採用下面這段代碼:
Console cons=System.console();String username=cons.readline("User name: ");char []passwd=cons.readPassword("Password: ");
為了安全起見,返回的密碼存放在一維字元數組中,而不是字串中。在對密碼進行處理之後,應該馬上用一個填儲值覆蓋數組元素。
採用Console對象處理輸入不如採用Scanner方便。每次只能讀取一行輸入,而沒有能夠讀取一個單詞或者一個數值的方法。
通過StringTokenizer類可以分解輸入的整行得到的帶空格的字串。預設情況下,StringTokenizer以空格、定位字元、分行符號和斷行符號符作為分割依據。
import java.util.Scanner;import java.util.StringTokenizer;class Main { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println("輸入資料:"); StringTokenizer stringTokenizer=new StringTokenizer(scanner.nextLine()); System.out.println("分隔後:"); while(stringTokenizer.hasMoreTokens()){ System.out.println(stringTokenizer.nextToken()); } }}
運行結果:
輸入資料:runoob com分隔後:runoobcom
Scanner不僅能從輸入資料流中讀取,也能從檔案中讀取,除了構建Scanner對象的方法,其他和上文給出的完全相同,以下案例從一個名叫test.txt的檔案中讀取整數。
test.txt檔案內容:
12345
Fileio.java檔案內容:
import java.io.File;import java.io.FileNotFoundException;import java.util.Scanner;public class Fileio { public static void main(String[] args) throws FileNotFoundException { int[] arr=new int[10]; int i=0; Scanner sc=new Scanner(new File("F:/test.txt")); while(sc.hasNextInt()) { arr[i]=sc.nextInt(); i++; } sc.close(); System.out.printf("讀取了 %d 個數\n",i); for(int j=0;j<i;j++) { System.out.println(arr[j]); } }}
運行結果:
讀取了 5 個數12345
原文地址