1輸入與輸出
input | 某個裝置或者環境進行資料的輸入 |
output | 某個裝置或者環境進行資料的輸出 |
在java中,java将輸入輸出抽象為流對象(IO流)來解決,我們以檔案裝置來解釋:
輸入流 | 從檔案讀取資料或者從鍵盤輸入資料 |
輸出流 | 向檔案寫入資料 |
Io流在java中又分為位元組流和字元流:
位元組流 | 所有檔案的儲存是都是位元組(byte)的儲存,在磁盤上保留的并不是檔案的字元而是先把字元編碼成位元組,再儲存這些位元組到磁盤。在讀取檔案(特别是文本檔案)時,也是一個位元組一個位元組地讀取以形成位元組序列 |
字元流 | 字元流處理的單元為2個位元組的Unicode字元,分别操作字元、字元數組或字元串,而位元組流處理單元為1個位元組,操作位元組和位元組數組。是以字元流是由Java虛拟機将位元組轉化為2個位元組的Unicode字元為機關的字元而成的,是以它對多國語言支援性比較好! |
2、字元流
字元輸出流超類 | 字元輸出流子類 |
Writer | FileWriter |
BufferedWriter |
字元輸入流超類 | 字元輸入流子類 |
Reader | FileReader |
BufferedReader |
(1) 字元輸出流FileWriter
FileWriter的構造方法:
FileWriter(File file) | 根據給定的file對象構造一個FileWriter對象 |
FileWriter(String filename) | 根據給定的檔案名對象構造一個FileWriter對象 |
舉例:使用字元流向一個檔案輸出Hello World!
步驟:
1) 建立檔案;
2) 建立輸出流對象;
3) 把輸出流對象指向檔案;
4) 清空緩存。
5) 關閉輸出流
package com.file;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class FileCreate {
public static void main(String[] args) {
//建立file對象
File file=null;
FileWriter fw=null;
try {
//建立檔案
file=new File("D:/test/newFile.txt");
file.createNewFile();
//建立檔案輸出流
fw=new FileWriter(file);
//把内容寫入檔案
fw.write("Hello World!");
//清空緩存,把内容寫入檔案
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fw!=null){
try {
//關閉輸出流
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
當我們每次使用輸出流向檔案裡寫輸出資料的時候,寫入資料會覆寫檔案裡原有資料,若是我們想要檔案裡原有資料不被覆寫,我們可使用FileWrite的追加構造方法:
FileWriter(File file,boolean append) | 構造方法的第二個boolean參數用來表示是否追加 |
FileWriter(String filename, boolean append) |
例如我們再向上例中Hello World!後追加Hello China!
package com.file;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class FileCreate {
public static void main(String[] args) {
//建立file對象
File file=null;
FileWriter fw=null;
try {
//建立檔案
file=new File("D:/test/newFile.txt");
file.createNewFile();
//建立檔案輸出流,輸出資料将追加在檔案中原有資料後面
fw=new FileWriter(file,true);
//把内容寫入檔案
fw.write("Hello China!");
//清空緩存,把内容寫入檔案
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fw!=null){
try {
//關閉輸出流
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
從上裡可以看出,兩次輸入的資料(Hello World!Hello China!)是在一行,如果我們想讓追加後的資料另起一行呢
在輸入資料時“\r\n”表示換行,效果如下:
package com.file;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class FileCreate {
public static void main(String[] args) {
//建立file對象
File file=null;
FileWriter fw=null;
try {
//建立檔案
file=new File("D:/test/newFile.txt");
file.createNewFile();
//建立檔案輸出流,輸出資料将追加在檔案中原有資料後面
fw=new FileWriter(file,true);
//把内容寫入檔案,并換行
fw.write("Hello Beijing!\r\n");
//清空緩存,把内容寫入檔案
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fw!=null){
try {
//關閉輸出流
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
在windows系統中“\r\n”表示換行
在Linux系統中“\n”表示換行
在ios系統中“\r”表示換行
FilterWriter的writer方法還有其他寫入功能:
writer(Char[ ] chuf) | 寫入字元數組 |
writer(Char[ ] chuf,int offset,int length) | 寫入字元數組的某一部分 |
writer(int i) | 寫入單個字元(int轉換為ASCII) |
writer(String str) | 寫入字元串 |
writer(String [ ] str,int offset,int length) | 寫入字元串的某一一部分 |
其他相關方法清查與API
(2)字元輸入流FileReader
FileReader的構造方法:
FileReader(File file) | 在給定從中讀取資料的File的情況下傳建一個新的FileReader |
FileReader(String fileName) | 在給定從中讀取資料的File檔案名的情況下傳建一個新的FileReader |
舉例:使用字元流從一個檔案讀取資料!
步驟:
1) 建立輸入流對象;
2) 把輸出流對象指向檔案;
3) 讀取資料;
4) 關閉輸入流。
package com.file;
import java.io.*;
public class FileIO {
public static void main(String[] args) {
//建立FileReader對象
FileReader fr=null;
try {
//把輸入流指向需要讀取的檔案
fr=new FileReader("D:/test/newFile.txt");
//建立字元數組
char[] chars=new char[1024];
int num=-1;
//讀取資料,如果讀取完畢,則num将傳回-1
while ((num=fr.read(chars))!=-1){
//将字元數組中資料轉換為字元串并輸出到控制台
String str=new String(chars,0,num);
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(3)字元輸入流之BufferedReade
BufferedReader 由Reader類擴充而來,提供通用的緩沖方式文本讀取,而且提供了很實用的readLine,讀取一個文本行,從字元輸入流中讀取文本,緩沖各個字元,進而提供字元、數組和行的高效讀取。
BufferedReader提供了readLine()方法來讀取一行資料
package com.file;
import java.io.*;
public class FileIO {
public static void main(String[] args) {
//建立FileReader對象
FileReader fr=null;
//BufferedReader
BufferedReader br=null;
try {
//把輸入流指向需要讀取的檔案
fr=new FileReader("D:/test/newFile.txt");
//用BufferedReader包裝FileReader
br=new BufferedReader(fr);
//建立字元串
String str=null;
//讀取資料,如果讀取完畢,則str将傳回null
while ((str=br.readLine())!=null){
//将字元串輸出到控制台
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fr!=null){
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(4)字元輸入流之BufferedWriter
将文本寫入字元輸出流,緩沖各個字元,進而提供單個字元、數組和字元串的高效寫入。可以指定緩沖區的大小,或者接受預設的大小。在大多數情況下,預設值就足夠大了。 該類提供了 newLine() 方法,它使用平台自己的行分隔符概念。
package com.file;
import java.io.*;
public class FileCreate {
public static void main(String[] args) {
//建立file對象
File file=null;
FileWriter fw=null;
BufferedWriter bw=null;
try {
//建立檔案
file=new File("D:/test/newFile.txt");
if (!file.exists()){
file.createNewFile();
}
//建立檔案輸出流,輸出資料将追加在檔案中原有資料後面
fw=new FileWriter(file,true);
//用BufferedWriter包裝FileWriter
bw=new BufferedWriter(fw);
//把内容寫入檔案,并換行
bw.write("Hello Xian!");
bw.newLine();
bw.write("Hello madi");
//清空緩存,把内容寫入檔案
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fw!=null){
try {
//關閉輸出流
bw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3、位元組流
(1)位元組輸出流OutputStream
OutputStream是整個IO包中位元組輸出流的最大父類,此類是一個抽象類,如果想要使用此類的話,則首先必須通過子類執行個體化對象,那麼如果現在要操作的是一個檔案,則可以使用:FileOutputStream類。通過向上轉型之後,可以為OutputStream執行個體化。具體事例如下:
package com.file;
import java.io.*;
public class OutputStreamDemo {
public static void main(String[] args) {
//建立檔案對象
File file = new File("D:/test/newFile2.txt");
//聲明輸出流
OutputStream os=null;
try {
//将輸出流指向檔案對象
os=new FileOutputStream(file);
String str="Hello World";
byte[] bytes=str.getBytes();
//向指定檔案輸出資料
os.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(os!=null){
try {
//關閉輸出流
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}}}
(2)位元組輸入流InputStream
既然程式可以向檔案中寫入内容,則就可以通過InputStream從檔案中把内容讀取進來,
與OutputStream類一樣,InputStream本身也是一個抽象類,必須依靠其子類,如果現在是從檔案中讀取,就用FileInputStream來實作。具體事例如下:
package com.file;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamDemo {
public static void main(String[] args) {
//構造一個檔案輸入流對象
InputStream is=null;
try {
//将輸入流對象指向檔案
is=new FileInputStream("D:/test/newFile2.txt");
byte[] bytes=new byte[1024];
//temp用來存儲讀入的位元組長度
int temp;
//循環讀取資料
while ((temp=is.read(bytes))!=-1){
String str=new String(bytes,0,temp);
System.out.print(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (is!=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(3)位元組輸入流之InputStreamReader
InputStreamReader将位元組流轉換為字元流。是位元組流通向字元流的橋梁。如果不指定字元集編碼,該解碼過程将使用平台預設的字元編碼。
構造方法:
構造一個預設編碼集的InputStreamReader類 | InputStreamReader isr = new InputStreamReader(InputStream in); |
構造一個指定編碼集的InputStreamReader類 | InputStreamReader isr = new InputStreamReader(InputStream in,String charsetName); |
package com.file;
import java.io.*;
public class InputStreamDemo {
public static void main(String[] args) {
//構造一個檔案輸入流對象
InputStream is=null;
InputStreamReader isr=null;
try {
//将輸入流對象指向檔案
is=new FileInputStream("D:/test/newFile2.txt");
//用InputStreamReader包裝FileInputStream
isr=new InputStreamReader(is);
char[] chars=new char[1024];
//temp用來存儲讀入的位元組長度
int temp;
//循環讀取資料
while ((temp = isr.read(chars))!= -1){
String str=new String(chars,0,temp);
System.out.print(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (isr!=null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is!=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(4)位元組輸出流之OutputStreamWriter
OutputStreamWriter将位元組流轉換為字元流。是位元組流通向字元流的橋梁。如果不指定字元集編碼,該解碼過程将使用平台預設的字元編碼。
構造方法:
構造一個預設編碼集的OutputStreamWriter類 | OutputStreamWriter osw = new OutputStreamWriter(OutputStream out); |
構造一個指定編碼集的OutputStreamWriter類 | OutputStreamWriter osw = new OutputStreamWriter(OutputStream out,String charsetName); |
package com.file;
import java.io.*;
public class OutputStreamDemo {
public static void main(String[] args) {
//建立檔案對象
File file = new File("D:/test/newFile2.txt");
//聲明輸出流
OutputStream os=null;
//聲明OutputStreamWriter對象
OutputStreamWriter osw=null;
try {
//将輸出流指向檔案對象
os=new FileOutputStream(file,true);
//用OutputStreamWriter包裝OutputStream
osw=new OutputStreamWriter(os);
String str="\r\nHello China!";
//向指定檔案輸出資料
osw.write(str);
osw.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (osw!=null){
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os!=null){
try {
//關閉輸出流
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}