【面試之java io流】IO
一.IO
1.IO概念
·輸入流:把能夠讀取一個位元組序列的物件稱為輸入流(百度百科)
·輸出流:把能夠寫一個位元組序列的物件稱為輸出流(百度百科)
從定義上看可能會讓你感到困惑,這裡解釋一下:輸入輸出是相對於記憶體裝置而言的,將外設(硬碟,鍵盤等)中的資料讀取到記憶體裝置中叫輸入;將記憶體裝置中的資料寫入到外設中叫輸出,所以有讀入,寫出的稱呼:讀入到記憶體,寫出記憶體。
可以這樣比喻:輸入流和輸出流中間連線著記憶體,輸入流和輸出流將讀寫分離開來進行操作,先從外設讀入記憶體,然後再寫出記憶體轉移到其他外設。
·總體結構圖(摘自網友)
2.位元組流
·兩個頂層父類 (抽象類)及實現類
·InputStream(讀入記憶體) :所有位元組輸入流相關類的父類
··FileInputStream :obtain input bytes from a file in a file system,for reading streams of raw bytes(原始位元組) such as image data..For
writing streams of characters,consider using FileReader
初始化時(建構函式)要和檔案關聯,讀取的物件,要首先判斷檔案是否存在
——read():read a byte of data from this inputStream.
——read(byte [] b):read up to b.length bytes of data from this inputStream into an array of bytes.
——read(byte [] b,int off,int length)
——close()
import java.io.*;
/**
* Created by 111 on 2016/1/29.
*/
public class Demo1 {
public static void main(String [] args){
File file = new File("d:/helloWorld.txt");
InputStream in = null;
try {
if (!file.exists()){ //檔案不存在則建立
file.createNewFile();
}
in = new FileInputStream(file);
byte [] buf = new byte[1024]; //先寫到快取中,然後再一起寫到其他外設中
int length = 0;
while ((length=in.read(buf))!=-1){ //-1 represent the end of the file is reached ,
//位元組一個一個地讀入到記憶體
System.out.println(new String(buf,0,length)); //需要將int轉為位元組,如果為中文的話輸出亂碼字元 ,
//此處其實是寫出到了外設(控制檯)上,System.out返回的是PrintStream物件
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
··ByteArrayInputStream:包含一個內建的緩衝器儲存位元組
建構函式要和位元組陣列相關聯:byte [] buff
——read():從輸入流中讀取下一個位元組
——read(byte [] buff,int off,int len):
——close():關閉後並沒有影響,類中的方法仍然可以呼叫而不丟擲IO異常
·OutputStream(寫出記憶體):所有和輸出位元組流相關類的父類
··FileOutputStream:for writing data to a file or a FileDescriptor,for writing streams of raw data(原始位元組)such as image data.For writing streams of characters,consider using FileWriter.
初始化時要和檔案關聯,寫出的目的地。沒有該檔案時會自動建立。
——write(int b):write the specified(指定的) byte to this file output stream.
——write(byte [] b):
——write(byte [] b,int off,int len)
——close()
import java.io.*;
/**
* Created by 111 on 2016/2/25.
*/
public class Demo2 {
public static void main(String [] args){
File file = new File("d:/helloWorld3.txt"); //沒有<span style="font-family:KaiTi_GB2312;">會自動建立</span>
OutputStream out = null;
try {
out = new FileOutputStream(file);
out.write(69); //檔案中產生ASC碼對應的字元
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
★ FileInputStream & FileOutputStream 協同完成檔案複製(不會亂碼)
import java.io.*;
/**
* Created by 111 on 2016/2/25.
*/
public class Demo3 {
/**
* 從一個檔案複製到另一個檔案
* @param args
*/
public static void main(String [] args){
File origin = new File("d:/helloWorld.txt");//原始檔案
if (!origin.exists()){
try {
origin.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
File destination = new File("d:/helloWorld4.txt");//目的檔案
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(origin);
out = new FileOutputStream(destination);
byte [] buff = new byte[1024];
int len = 0;
while ((len=in.read(buff))!=-1){
out.write(buff,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null){
in.close();
}
if (out != null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3.字元流
·兩個頂層父抽象類及其實現類
·Reader:for reading character streams
··InputStreamReader:從位元組流到字元流的橋樑:讀取位元組流然後按指定的編碼方式進行解碼(看不懂→能看懂)
建構函式要和輸入流InputStream/編碼方式Charset相關聯:System.in/FileInputStream傳入
——read() :讀入一個字元
——read(char [] cbuf,int offset,int length)
——close()
···FileReader:讀字元檔案的方便類,本質是InputStreamReader在構造時 指定了預設的編碼方式,用於讀取字元流
建構函式要和檔案相關聯
★InputStreamReader 接收鍵盤上輸入的資料,寫入檔案中(中文會亂碼)
import java.io.*;
/**
* Created by 111 on 2016/2/25.
*/
public class Demo4 {
/**
* 控制檯輸入,寫到資料夾中
* @param args
*/
public static void main(String [] args){
File file = new File("d:/helloWorld.txt");//會覆蓋之前的資料
OutputStream out = null;
InputStreamReader reader = null;
try {
reader = new InputStreamReader(System.in);
out = new FileOutputStream(file);
int len = 0;
while ((len = reader.read())!= -1){
out.write(len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
··BufferedReader:從一個字元輸入(character-input)流中讀取文字(text),並進行緩衝字元,預設快取8192(8M),行最長80
建構函式要和Reader in/int size 關聯:InputStreamReader
——in read()
——in read(char [] cbuf,int off,int len)
——String readLine()
——close()
★鍵盤錄入,使用快取
BufferedReader buffr = new BufferedReader(new InputStreamReader(System.in))
·Writer:for writing to character streams (字元流的寫操作基本上後面都需要進行flush()操作)
··OutputStreamWriter :從字元流到位元組流的橋樑:寫出的字元被用指定的編碼方式進行編碼。
建構函式要和OutputStream out/charset 關聯:System.out/FileOutputStream
——write(int c):寫一個單獨的字元
——write(char [] cbuf,int off,int len)
——write(String str,int off,int len)
——flush():重新整理流
——close()
···FileWriter:寫字元檔案的方便類,實質是:OutputStreamWriter指定了預設的本機編碼方式,且可以處理檔案
··BufferedWriter:寫文字到一個字元輸出(character-out)流,並對傳入的字元進行快取
建構函式要和 Writer out/int size 相關聯
——write(int c):寫一個單獨的字元
——write(char [] cbuf,int off,int len)
——write(String str,int off,int len)
——newLine():換行
——flush():重新整理流
——close()
★控制檯輸出,使用快取
BufferedWriter buffw= new BufferedWriter(new OutputStreamWriter(System.out,"utf-8"));
★鍵盤輸入,控制檯輸出功能
import java.io.*;
/**
* Created by 111 on 2016/2/26.
*/
public class Demo5 {
/**
* 鍵盤輸入,控制檯輸出
* @param args
*/
public static void main(String[]args){
BufferedReader buff = null;
BufferedWriter bufferedWriter = null;
String line = null;
try {
buff = new BufferedReader(new InputStreamReader(System.in,"utf-8"));
bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out,"utf-8"));
<span style="font-family:SimSun;">while</span> ((line=buff.readLine())!=null){
bufferedWriter.write(line);
<span style="font-family:KaiTi_GB2312;"> <span style="font-family:SimSun;"> }</span></span>
bufferedWriter.flush(); //一定要重新整理
} catch (IOException e) {
e.printStackTrace();
} finally {
if (buff!=null){
try {
buff.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
☆面試題:簡述一下將檔案中的資料輸入到另一個檔案中的步驟
1.首先建立File物件,並且和需要操作的檔案相關聯,這時候需要對檔案進行判斷是否存在,不存在則會報錯
2.既然是讀取檔案並且寫到檔案,屬於純文字,可以選擇FileReader和FileWriter進行讀寫操作,如果出現亂碼可以使用其父類指定編碼方式
3.建立FileReader物件用於讀取檔案中的資料,這裡可以使用緩衝流進行處理,提高效率,建立一個BufferedReader物件
BufferedReader buffr = new BufferedReader(new InputStreamReader(new FileReader(file)));
4.建立FileWriter,同上使用快取
★程式碼如下
import java.io.*;
/**
* Created by 111 on 2016/2/26.
*/
public class Demo6 {
public static void main(String[] args){
File origin = new File("d:/helloWorld.txt");
File destination = new File("d:/helloWorld6.txt");
InputStreamReader in = null;
OutputStreamWriter out = null;
BufferedReader reader = null;
BufferedWriter writer = null;
if (!origin.exists()){
try {
origin.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(origin),"ISO-8859-1"));
// reader = new BufferedReader(new FileReader(origin));
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination),"ISO-8859-1"));
String line = null;
while ((line = reader.readLine())!=null){
writer.write(line);
writer.newLine();
}
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader!= null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer!=null){
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}