1. 程式人生 > 實用技巧 >java基礎:I/O學習筆記

java基礎:I/O學習筆記

I/O流

Java.io.file類

File類是Java程式中表示檔案和目錄(資料夾)的方式,是檔案和目錄的路徑名的抽象表示形式,我們可以使用File類對檔案和資料夾進行操作。路徑名是檔案或目錄的路徑和名稱的字串形式。

我們可以使用File類的方法:

建立檔案或資料夾

刪除檔案或資料夾

獲取檔案或資料夾

判斷檔案或資料夾是否存在

對資料夾進行遍歷和篩選

獲取檔案的大小

File類的靜態變數:

static String pathSeparator; 與系統有關的檔名稱分割分隔符,Windows系統是 ; Linux系統是 : 為了方便使用,它表示為一個字串。(原始碼:public static final String pathSeparator=""+ pathSeparatorChar)

static char pathSeparatorChar; 與系統有關的路徑分隔符。

static String separator; 與系統有關的檔名稱分割分隔符,Windows系統是 \ Linux系統是 / 為了方便使用,它表示為一個字串。(原始碼:public static final String Separator=""+ SeparatorChar)

static char separatorChar; 與系統有關的預設名稱分割分隔符。

File類表示檔案的方式是與系統無關的,但路徑名錶示檔案的方式是與系統有關的,不同系統的檔名分割符不同,因此跨平臺執行的Java軟體的路徑名需要用File類的靜態變數代替字元分割符。

Windows寫法:"C:\\java\\bin"

Linux寫法:"C:/java/bin"

通用寫法:"C: "+File.separator+"java" +File.separator+"bin"

路徑不區分大小寫,Java中\表示轉義字元,因此Windows上表示一個檔案的路徑,在Java程式中需要使用\\來表示\目錄分隔符。

File類的構造方法:

File(String pathname) 通過將引數傳遞的路徑名字串轉換為抽象路徑來建立一個的File類物件,表示一個檔案或資料夾。

String pathname :字串形式的路徑名稱,表示此File類物件的位置,該路徑名最後一段是此File物件的名稱。傳遞的可以是真路徑也可以是假路徑,可以是絕對路徑也可以是相對路徑,絕對路徑是一個完整的路徑,以碟符開始,相對路徑是一個簡化的路徑,以當前目錄為根目錄開始。


File f1 = new File("C:\\Program Files\\MySQL");
System.out.println(f1); //File類重寫了Object類的toString方法,所以直接列印File物件的引用會打印出構造方法中傳遞的路徑名字串 C:\Program Files\MySQL

File f0 = new File("C:\\Program Files\\SB");
System.out.println(f0); //不存在的SB資料夾,仍然打印出C:\\Program Files\\SB

File(String parent,String child) 根據parent父路徑字串和child子路徑字串建立一個File例項,好處是父路徑和子路徑可分開書寫,父路徑和子路徑都可以單獨變化,使用起來非常靈活。

String parent = "C:\\ProgramFiles\\";
File f2 = new File(parent, "MySQL");
File f3 = new File(parent, "Huawei");
System.out.println(f2);//C:\ProgramFiles\MySQL
System.out.println(f3);//C:\ProgramFiles\Huawei

File(File parent,String child) 根據parent抽象路徑名和child子路徑字串建立一個File例項,好處是父路徑和子路徑可分開書寫,父路徑和子路徑都可以單獨變化,使用起來非常靈活。而且父路徑是File型別,可以使用File方法對路徑進行一些操作,再使用路徑建立物件。

File parent = new File("C:\\ Program Files\\");
File f4 = new File(parent," MySQL");
File f5 = new File(parent," Huawei");
System.out.println(f4);//列印了 C:\Program Files\MySQL
System.out.println(f5);//列印了 C:\Program Files\ Huawei

File類常用方法

獲取功能的方法:

public String getAbsolutePath() 返回此File物件的絕對路徑名。無論構造方法中傳遞的路徑是絕對的還是相對的,呼叫該方法獲取的都是絕對路徑名字串。

File f1= new File("MySQL");
String path1=f1. getAbsolutePath ();
System.out.println(path1);//列印了 C:\\Program Files\\MySQL

public String getPath() 獲取此File物件的構造方法中傳遞的路徑名字串。
File類的toString方法就呼叫了該方法。原始碼:public String toString(){return getPath();}


File f2= new File("Program Files\\MySQL");
String path2=f2. getPath ();
System.out.println(path1);//列印了 Program Files\\MySQL

public String getName() 返回由此File物件表示的檔案或資料夾的名稱,即獲取構造方法中傳遞的路徑名的結尾部分。

File f1= new File("C:\\Program Files\\MySQL");
String name1=f1.getName();
System.out.println(name1);//列印了 MySQL

public long length () 返回由此File物件表示的檔案的大小,獲取的是構造方法中指定的檔案的大小,以位元組為單位。資料夾沒有大小,呼叫length()方法返回0。如果構造方法中傳遞的路徑不存在,呼叫length()方法也返回0。

File f1 = new File("D:\\桌布\\寶兒姐.jpg");
File f2 = new File("D:\\桌布");
File f3 = new File("D:\\桌布\\馮寶寶.jpg ");//沒有這張照片
long size1 = f1.length();
long size2 = f2.length();
long size3 = f3.length();
System.out.println(size1);//列印了 125410(單位是位元組)
System.out.println(size2);//列印了 0
System.out.println(size3);//列印了 0

判斷類方法:

public boolean exists () 根據構造方法中傳遞的路徑名(可以是相對路徑名)判斷此File物件表示的檔案或資料夾(目錄)是否存在。
public boolean isDirectory () 根據構造方法中傳遞的路徑名(可以是相對路徑名)判斷此File物件表示的是否是目錄。
public boolean isFile () 根據構造方法中傳遞的路徑名(可以是相對路徑名)判斷此File物件表示的是否是資料夾。

電腦的資料夾中只由檔案和資料夾,所有以上兩個方法是互斥的。使用這兩個方法的前提是構造方法的路徑必須存在。

File f1 = new File("C:\\Program Files\\MySQL");
if(f1.exists()){//判斷MySQL是否存在
boolean b1=f1.isFile();//判斷是否是檔案
System.out.println(b1);}//打印出false

File f2 = new File("C:\\Program Files\\MySQL");
if(f2.exists()){//判斷MySQL是否存在
boolean b2=f2.isDirectory();//判斷是否是資料夾
System.out.println(b2);}//打印出true

建立和刪除的方法:

public boolean createNewFile() 當且僅當此File物件表示的路徑名的最後一段(即檔名)不存在時,建立一個由此路徑名命名的空檔案。注意:此方法聲明瞭可能會丟擲的異常IOException,當該File物件的路徑不存在時,呼叫此方法會丟擲異常,所以呼叫此方法時必須處理此異常。建立成功返回值為true,否則為false。

try { File f1 = new File("D:\\KuGou\\1.txt");
boolean b1 = f1.createNewFile();
System.out.println(b1); //建立成功,列印true
} catch (IOException e) { e.printStackTrace();}


public boolean mkdir() 建立由此File物件表示的目錄,只能建立單級資料夾。建立成功返回true,路徑不存在不會丟擲異常,也不會建立目錄,返回值也是true,目錄名已存在時返回false。
File f2 = new File("D:\\KuGou\\music");
boolean b2 = f2.mkdir();
System.out.println(b2);//建立成功,列印true

public boolean mkdirs() 建立由此File物件表示的目錄,包括任何必須但不存在的父目錄。此方法可以建立多級資料夾。
File f3 = new File("D:\\KuGou\\music\\ChineseMusic");
boolean b3 = f3.mkdir();
System.out.println(b3); //建立成功,列印true
public boolean delete() 刪除由此File物件表示的檔案或目錄。刪除成功返回true,資料夾中有內容或構造方法中給出的路徑不存在都返回false。注意:此方法直接從硬碟中刪除檔案或目錄,不走回收站,謹慎使用。
File f4 = new File("D:\\KuGou\\music\\ChineseMusic");
boolean b4 = f4.delete();
System.out.println(b4);//刪除成功,列印true
遍歷目錄的方法:
public String[] list() 遍歷此File物件表示的目錄,獲取目錄中的檔案和子目錄的名稱,並存儲到一個String陣列中作為返回值。如果構造方法中給出目錄的路徑不存在或不是目錄(是檔案)都會丟擲空指標異常。

File f1 = new File("D:\\KuGou");
String[] list1 = f1.list();
for (String fileName : list1) {
System.out.println(fileName); } //打印出該目錄下所有檔案和子目錄的名稱

public File[] listFiles()遍歷此File物件表示的目錄,獲取目錄中的檔案和子目錄的路徑名,封裝為File物件儲存到一個File陣列中作為返回值,新的File物件也可以呼叫File類的方法,因而用途更廣。如果構造方法中給出目錄的路徑不存在或不是目錄(是檔案)都會丟擲空指標異常。

File f2 = new File("D:\\KuGou");
File[] files = f2.listFiles();for (File file2 : files) { System.out.println(file2); } //呼叫了toString方法,打印出該目錄下所有檔案和子目錄的路徑名

遞迴列印多級目錄:

public static void main(String[] args) {
File f1 = new File("D:\\KuGou");
getAllFile(f1);
}
public static void getAllFile(File dir){//定義遞迴方法
System.out.println(dir);//列印引數中的目錄路徑名
File[] files = dir.listFiles();//遍歷引數中的目錄,把該目錄中的檔案和子目錄封裝成File物件儲存到File陣列中
for (File f2 : files) {//遍歷File陣列
if (f2.isDirectory()){//判斷陣列元素是否是資料夾
getAllFile(f2);}else {//把資料夾作為引數再呼叫本函式進行遍歷
System.out.println(f2);}//列印檔案的路徑名
}
}

遞迴搜尋目錄中的mp3檔案:

public static void main(String[] args) {
File f1 = new File("D:\\KuGou");
getAllFile(f1);}
public static void getAllFile(File dir){//定義遞迴方法
File[] files = dir.listFiles();/*遍歷引數中的目錄,把該目錄中的檔案和子目錄封裝成File物件儲存到File陣列中*/
for (File f2 : files) {//遍歷File陣列
if (f2.isDirectory()){//判斷陣列元素是否是資料夾
getAllFile(f2);}else //把資料夾作為引數再呼叫本函式進行遍歷
{
String name = f2.getName();//獲取此File物件的檔名並轉換成字串
boolean b = name.endsWith(".mp3");//判斷檔名的字尾名是否是.mp3
if (b){System.out.println(f2);}//列印字尾名是.mp3的檔名。

/* D:\KuGou\music\download\祖婭納惜 - 全都是戲.mp3
D:\KuGou\music\download\祖婭納惜 - 大氿歌.mp3
D:\KuGou\music\download\祖婭納惜 - 天下局.mp3
D:\KuGou\music\download\祖婭納惜 - 水上燈.mp3
D:\KuGou\music\download\祖婭納惜 - 百家策.mp3
D:\KuGou\music\download\祖婭納惜 - 繁華唱遍.mp3
D:\KuGou\music\download\祖婭納惜 - 蘇幕遮.mp3
*/ }
}
}

帶過濾器的遍歷方法:

public File[] listFiles (FileFilter filter) 遍歷此File物件表示的目錄,獲取目錄中的檔案和子目錄的路徑名,封裝為File物件傳遞給引數中的過濾器,並把滿足過濾規則的File物件儲存到一個File陣列中作為返回值。

Java.io.FileFilter:檔案過濾器介面,該介面只有一個抽象方法:boolean accept(File pathname)。使用此過濾器要建立該介面的實現類並重寫此方法,自定義過濾規則,引數中的File物件滿足過濾規則時返回值為true,否則為false。listFiles (FileFilter filter)方法會把遍歷目錄得到的每個File物件傳遞給FileFilter介面的例項的boolean accept(File pathname)方法並接收其返回值,返回值為true時,就會把此File物件儲存到一個File陣列中。

用過濾器搜尋目錄中大於10mb的檔案:

public static void main(String[] args) {
File f1 = new File("D:\\KuGou\\music");
getAllFile(f1);
}
public static void getAllFile(File dir){
File[] files = dir.listFiles(new FileFilter() {//建立一個檔案過濾器介面的實現類(匿名內部類)
@Override
public boolean accept(File pathname) {//重寫檔案過濾器介面的accept方法
if (pathname.isDirectory()) return true;
/*如果此File物件是資料夾,則返回true,該資料夾會被放到File[]中繼續遍歷。*/
return pathname.length()>10*1024*1024;
/*如果此File物件大於10mb,則返回true,
該檔案會被放入File[]中。*/
}
} );//
/*遍歷引數中的目錄,把該目錄中的檔案和子目錄封裝成File物件傳遞給filter1()過濾器,把滿足過濾規則的File物件儲存到陣列中*/
for (File f2 : files) {//遍歷File陣列
if (f2.isDirectory()) {getAllFile(f2);}//把是資料夾的File物件再呼叫本方法遍歷
else{
System.out.println(f2);//把滿足過濾條件的File物件打印出來
}
}
}

IO流:

流是一種抽象概念,它代表了資料的無結構化傳遞。按照流的方式進行輸入輸出,資料被當成無結構的位元組序或字元序列。IO流就是以流的方式進行輸入輸出。Java程式通過IO流向記憶體,硬碟,網路等裝置輸入和輸出資料。所謂的輸入輸出是相對程式而言的。

java.io.OutputStream 位元組輸出流

此抽象類是表示輸出位元組流的所有類的超類。

定義了一些共性的成員方法:

public void close()

關閉此輸出流並釋放與此流相關聯的任何系統資源。
public void flush()
重新整理此輸出流並強制任何緩衝的輸出位元組被寫出。
public void write(byte[] b)
將 b.length位元組從指定的位元組陣列寫入此輸出流。
public void write(byte[] b, int off, int len) 從指定的位元組陣列寫入 len個位元組,從陣列索引off開始輸出到此輸出流。
public abstract void write(int b) 將指定的位元組寫入此輸出流。

重要子類:

java.io.FileOutputStream extends OutputStream

檔案位元組輸出流,用於從記憶體中的程式向硬碟中的檔案寫入資料。

構造方法:

public FileOutputStream(String name) 建立一個FileOutputStream物件。根據構造方法中傳遞的路徑名建立一個空的檔案,如果存在同名的檔案就覆蓋舊的檔案。把建立好的FileOutputStream物件指向建立好的檔案。

public FileOutputStream(String name, boolean append) 第二個引數是續寫開關,如果為true,就不覆蓋同名舊檔案,把此File-OutputStream物件指向舊檔案的末尾。如果為false就和上面的方法一樣。

public FileOutputStream(File file) 建立一個FileOutputStream物件並指向寫入資料的檔案。

public FileOutputStream(File file, boolean append) 第二個引數是續寫開關,同上。 

輸出資料的原理:(記憶體 à 硬碟)

Java程式 à JVM(Java虛擬機器)à OS(作業系統)à OS調研自己的輸出資料方法 à 把程式中的資料寫入到檔案中

硬碟中儲存的資料都是以位元組為基本單位的二進位制整數,所以使用IO流輸入輸出的資料都是二進位制整數,輸入十進位制整數會自動轉換為二進位制整數。一個位元組用八位二進位制整數表示(10101010),換算為十進位制範圍是-128~127,更大的資料由多個位元組組成,如一個int型別由四個位元組(32位二進位制數)組成。此方法的引數使用int型別是為了後續使用方便,其實在OutputStream介面的設計中定義了int型別只寫入低8位二進位制整數,高24位被忽略,所以引數還是一個位元組,當int型別變數的值不超過-128~127範圍時int型別的高24位全都是0,被忽略也不影響,當int型別變數值超過 -128~127範圍時高24位不全為0,也就不止一個位元組,但高24位被忽略了,有效值還是低8位表示的不超過-128~127範圍的整數,還是一個位元組。

Windows系統的記事本把十進位制表示為0~127的位元組查詢ASCII表顯示,把十進位制表示為-128~-1的位元組結合後一個位元組查詢系統預設碼錶(GBK)顯示。

public static void main(String[] args) throws IOException{//宣告可能丟擲的異常
FileOutputStream fos1 = new FileOutputStream("D:\\KuGou\\a.txt");
/* 建立一個FileOutputStream物件,引數中傳遞寫入資料的目的地。a.txt是新建的檔案,即使該檔案存在依然會新建並覆蓋舊的。*/
char b1 = 'K';
fos1.write(b1);/*char型別可以自動轉換成int型別再被write()方法強制轉化成位元組,英文字元都使用ASCII編碼,K對應ASCII表值為75,b1=75,75自動轉換成二進位制整數01001011寫入a.txt,用記事本開啟時會自動轉換為十進位制整數75查詢ASCII表,顯示K */
char [] b2 = {'u','G','o','u'};
for (int i = 0; i <4 ; i++) {
fos1.write(b2[i]);
}//一次一個位元組,迴圈寫入多個位元組。此時用記事本開啟a.txt顯示KuGou
fos1.close();/* 關閉此輸出流並釋放與此流相關聯的任何系統資源。(流的使用會呼叫系統的方法,使用完畢關掉流能提高程式效率)*/
File f1 = new File("D:\\KuGou\\a.txt");
FileOutputStream fos2 = new FileOutputStream(f1,true);//建立一個FileOutputStream物件指向a.txt的末尾。
int [] b3 = {50,48,50,48};
for (int i = 0; i <4; i++) {
fos2.write(b3[i]);
}//50和48對應ASCII表值為2和0 ,此時用記事本開啟a.txt顯示KuGou2020。
fos2.close();
FileOutputStream fos3 = new FileOutputStream(f1);//建立一個FileOutputStream物件指向新的空檔案a.txt,新的檔案會覆蓋舊檔案。
fos3.write(75);//此時用記事本開啟a.txt顯示K
fos3.close();
}

String類方法:public byte[] getBytes()使用平臺的預設字符集將此String編碼為位元組序列,將結果儲存到新的位元組陣列中。

public byte[] getBytes(String charsetName)使用引數的字串命名的字符集(編碼表)將呼叫此方法的String轉換為位元組序列,將結果儲存到新的位元組陣列中。

Arrays類方法:

public static String toString(byte[] a) 將引數的位元組陣列的內容轉換成字串表示形式。 字串表示由陣列元素的列表組成,括在方括號 "[]" 中。 相鄰的元素由字元", "分隔(逗號後跟一個空格)。

public static void main(String[] args) throws IOException{//宣告可能丟擲的異常
FileOutputStream fos = new FileOutputStream("D:\\KuGou\\a.txt");
/* 建立一個FileOutputStream物件,構造方法中傳遞輸出資料的目的地。a.txt是新建的檔案,即使該檔案存在依然會新建並覆蓋舊的。*/
byte [] b1 = "Music".getBytes();//把字串按ASCII編碼轉換成位元組序列並存儲到新的位元組陣列中。
byte [] b2 = " comes from life".getBytes();//空格也算一個位元組。
byte [] b3 = "生活".getBytes("GBK");//把字串按GBK編碼轉換成位元組序列並存儲到新的位元組陣列中。
System.out.println(Arrays.toString(b1));//[77, 117, 115, 105, 99]
System.out.println(Arrays.toString(b2));//[32, 99, 111, 109, 101, 115, 32, 102, 114, 111, 109, 32, 108, 105, 102, 101]
System.out.println(Arrays.toString(b3));//[-55, -6, -69, -18]
fos.write(b1);/*把陣列中的位元組序列寫入檔案中。用記事本開啟時會自動查詢ASCII編碼表,顯示Music */
fos.write(b2,0,12);/*把陣列中從索引0~12的位元組序列寫入檔案中。用記事本開啟時會自動查詢ASCII表,加上前面寫入的顯示Music comes from */
fos.write(b3);/*把陣列中的位元組序列寫入檔案中。用記事本開啟時遇到負數會自動結合後一個位元組查詢GBK編碼表,加上前面寫入的顯示Music comes from 生活*/
fos.close();
/* 關閉此輸出流並釋放與此流相關聯的任何系統資源。(流的使用會呼叫系統的方法,使用完畢關掉流能提高程式效率)*/
}

java.io.ByteArrayOutputStream extends OutputStream

表示輸出到記憶體中的byte陣列的位元組輸出流

java.io.InputStream 位元組輸入流

此抽象類是表示輸出位元組流的所有類的超類。

定義了一些共性的成員方法:

public void close() 關閉此輸入流並釋放與此流相關聯的任何系統資源。

public int read() 從該輸入流讀取一個位元組的資料。
public int read(byte[] b) 從該輸入流讀取最多b.length位元組的資料到位元組陣列。
public int read(byte[] b, int off, int len) 從該輸入流讀取最多len位元組的資料為位元組陣列。

重要子類:
Java.io.FileInputStream extends InputStream
檔案位元組輸入流,用於讓記憶體中的程式從硬碟中的檔案讀取資料。
構造方法:

FileInputStream(String name) 建立一個FileInputStream物件並指向引數傳遞的路徑名錶示的檔案。

FileInputStream(File file) 建立一個FileInputStream物件並指向要讀取的File物件表示的檔案。

輸入資料的原理:(硬碟à記憶體)

Java程式 à JVM(Java虛擬機器)à OS(作業系統)à OS調研自己的輸入資料方法 à 把檔案的資料讀取到程式中

重寫了父類的方法:
public int read() 按順序從該輸入流指向的檔案中讀取一個位元組並返回,讀取一個位元組後輸入流會自動指向下一個位元組,讀到檔案的末尾返回-1。
public static void main(String[] args) throws IOException{//宣告可能丟擲的異常
FileInputStream fis = new FileInputStream("D:\\KuGou\\a.txt");//此時用記事本

開啟a.txt顯示KuGou2020
/*建立一個FileInputStream物件並指向引數傳遞的檔案a.txt*/
int getByte = fis.read();//從a.txt讀取一個位元組作為返回值,用一個int變數接收。
System.out.print((char) getByte);//讀取到的位元組的值為75,對應的ASCII編碼表的值是'K',強制轉換成char型別打印出K
while ((getByte =fis.read())!=-1){//迴圈讀取多個位元組,每次迴圈讀取一個位元組,int變數只記錄本次讀取到的位元組,下一迴圈重新賦值。read()方法讀到檔案末尾返回-1停止迴圈。
System.out.print((char) getByte);//每讀取一個位元組就轉換成字元列印一次。最終打印出KuGou2020
}
fis.close();
}

public int read(byte[] b) 按順序從該輸入流指向的檔案中讀取最多b.length位元組並存儲到引數的位元組陣列中,引數中的陣列起緩衝作用,陣列的長度一般定義為1024(1kb)的整數倍。返回值是每次讀取的有效位元組數,讀到檔案的末尾返回-1。
String類的構造方法:

String(byte[]bytes) 通過使用平臺的預設字符集解碼將引數的位元組陣列用來構造新的String

String(byte[]bytes, intoffset, intlength) 通過使用平臺的預設字符集解碼將引數的位元組陣列的一部分轉換成字串。offset:轉換的開始索引,length:轉換的位元組個數。

public static void main(String[] args) throws IOException{//宣告可能丟擲的異常
FileInputStream fis = new FileInputStream("D:\\KuGou\\a.txt");//此時用記事本開啟a.txt顯示KuGou2020
/*建立一個FileInputStream物件並指向引數傳遞的檔案a.txt*/
byte[] bytes = new byte[1024];//定義一個緩衝陣列儲存讀取到的多個位元組。
int length ;//記錄每次讀取的有效位元組個數。
while ((length=fis.read(bytes))!=-1){//read(byte[] b)方法每次迴圈讀取最多1024個位元組,位元組陣列只記錄本次迴圈讀取到的位元組,下一次迴圈重新賦值。讀到檔案末尾返回-1停止迴圈。
System.out.println(new String(bytes,0,length));//把每讀取到的length個位元組一起轉換成一個字串打印出來。本次打印出KuGou2020
System.out.println("本次讀取位元組數:"+length);//本次讀取位元組數:9
}
fis.close();
}

檔案複製:一讀一寫
public static void main(String[] args) throws IOException{//宣告可能丟擲的異常
long s = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("D:\\桌布\\寶兒姐.jpg");/*建立一個FileInputStream物件,構造方法中繫結要讀取資料的檔案路徑名*/
FileOutputStream fos = new FileOutputStream("D:\\KuGou\\寶兒姐.jpg");/*建立一個FileOutputStream物件,構造方法中繫結要寫入資料的檔案路徑名*/
byte[] bytes = new byte[1024*10];//定義一個緩衝陣列儲存讀取到的多個位元組。
int length ;//記錄每次讀取的有效位元組個數。
while ((length=fis.read(bytes))!=-1){/*read(byte[] b)方法每次迴圈從fis連線的檔案讀取最多1024*10個位元組,緩衝陣列只記錄本次迴圈讀取到的位元組,下一次迴圈重新賦值。讀到檔案末尾返回-1停止迴圈。*/
fos.write(bytes,0,length);/*write(byte[] b int off int len)方法每次迴圈將緩衝陣列的length個位元組寫入fos建立的空檔案,最後一次迴圈length可能小於緩衝陣列的長度。*/
} fis.close();fos.close();
long e = System.currentTimeMillis();
System.out.println("複製檔案共耗時:"+(e-s)+" 毫秒");//複製檔案共耗時:2毫秒
}
Java.io.Writer:字元輸出流
此抽象類是所有字元輸入流的頂層父類,主要用於寫入字元,中文日文等象形文字佔一個字元兩個位元組,使用字元輸出流比較方便。
定義了一些共性的成員方法:
public void write(int c) 寫入引數傳遞的一個字元,Writer類自動把引數中的int型別轉換成char型別(忽略二進位制的高16位)。
public void write(char[] cbuf) 寫入引數傳遞的一個字元陣列。
public abstract void write(char[] cbuf, int off, int len) 寫入字元陣列的一部分。
public void write(String str) 寫入一個字串。
public void write(String str, int off, int len) 寫入一個字串的一部分。
public abstract void flush() 重新整理該流的緩衝資料。write方法會先把字元寫入緩衝區(字元轉換成位元組的過程),使用flush方法重新整理後才會寫入檔案中。
public void close() 先重新整理該流的緩衝資料,然後關閉此輸出流並釋放與此流相關聯的任何系統資源。

重要子類:

Java.io.FileWriter extends OutputStreamWriter extends Writer

檔案字元輸入流,用於把記憶體的程式的字元寫入到硬碟的檔案中。

構造方法:

FileWriter(File file) 建立一個FileWriter物件指向要寫入字元的檔案(File物件file代表的檔案)。

FileWriter(File file boolean append) 第二個引數是續寫開關,如果為true,就不覆蓋同名舊檔案,把此FileWriter物件指向舊檔案的末尾。如果為false就和上面的方法一樣。

FileWriter(String fileName) 建立一個FileWriter物件指向要寫入字元的檔案(路徑名fileName代表的檔案)。

FileWriter(String fileName boolean append)同上。

Java.io.Reader:字元輸入流
此抽象類是所有字元輸入流的頂層父類,主要用於讀取字元,中文日文等象形文字佔一個字元兩個位元組,使用字元字元輸入流比較方便。
定義了一些共性的成員方法:

public int read() 讀取一個字元並返回,char型別自動轉換成int型別。如果讀到字串末尾返回-1。

public int read(char[] cbuf) 一次讀取最多cbuf.length個字元,將字元儲存到緩衝陣列。返回讀取的字元數,如果讀到字串末尾返回-1。

public abstract int read(char[] cbuf, int off, int len) 一次讀取最多len個字元,將字元儲存到緩衝陣列,從陣列的off索引開始。返回讀取的字元數,如果讀到字串末尾返回-1。

public void close() 關閉此輸入流並釋放與此流相關聯的任何系統資源。如果讀到字串末尾返回-1。

重要子類:

Java.io.FileReader extends InputStreamReader extends Reader

檔案字元輸入流,用於把硬碟的檔案讀取到記憶體的程式中。

構造方法:

FileReader(File file) 建立一個FileReader物件指向要讀取字元的檔案(File物件file代表的檔案)。

FileReader(String fileName) 建立一個FileReader物件指向要讀取字元的檔案(路徑名fileName代表的檔案)。

public static void main(String[] args) throws IOException {//宣告可能丟擲的異常
FileWriter fw = new FileWriter("D:\\KuGou\\1.txt");//建立一個檔案字元輸出流物件指向檔案1.txt
char k = 'K';
fw.write(k);
fw.flush();/*向1.txt寫入一個字元'K','K'會根據ASCII編碼表轉換成byte型別的正數'75',
以二進位制形式儲存到硬碟的檔案中,重新整理後用記事本開啟顯示'K'*/
char[] g = {'u', 'G', 'o', 'u'};
fw.write(g);
fw.flush();//向1.txt寫入一個字元序列'u','G','o','u',重新整理後用記事本開啟顯示KuGou
String m = "Music";
fw.write(m);
fw.flush();/*向1.txt寫入一個字串"Music",其中每個字母都會根據ASCII編碼表轉換
成byte型別的正數儲存到硬碟的檔案中,重新整理後用記事本開啟顯示KuGouMusic*/
String s = "就是歌多";
fw.write(s);
fw.flush();/*向1.txt寫入一個字串"就是歌多",其中每個中文佔一個字元,每個字元
都會根據BGK編碼轉換成兩個byte型別的正數儲存到硬碟的檔案中,重新整理後用記事本開啟顯示KuGouMusic就是歌多*/
fw.close();
FileReader fr = new FileReader("D:\\KuGou\\1.txt");//建立一個檔案字元輸入流,構造方法中繫結要讀取字元的檔案路徑名
int getChar;
while ((getChar = fr.read()) != -1) {/*迴圈讀取多個字元,每次迴圈讀取一個字元,int變數只記錄本次讀取到的字元,
下一迴圈重新賦值。read()方法讀到檔案末尾返回-1停止迴圈。*/
System.out.print((char) getChar);/*每讀取一個字元列印一次。最終打印出KuGouMusic就是歌多*/
}
fr.close();
//複製一份中文資料。
long s = System.currentTimeMillis();
FileReader fr1 = new FileReader("D:\\樂器\\嗩吶.txt");
FileWriter fw1 = new FileWriter("D:\\KuGou\\嗩吶.txt");
char[] str = new char[1024*10];//定義一個緩衝陣列儲存讀取到的多個位元組。
int lenth;//記錄每次讀取的有效位元組個數。
while ((lenth = fr1.read(str)) != -1) {/*read(char[] cbuf)方法每次迴圈從fr1
連線的檔案讀取最多1024*10個字元,緩衝陣列只記錄本次迴圈讀取到的字元,下一次迴圈重新賦值。讀到檔案末尾返回-1停止迴圈。*/
fw1.write(str,0,lenth);/*write(char[] cbuf int off int len)方法每次迴圈將緩衝陣列的length個位元組
寫入fw1建立的空檔案,最後一次迴圈length可能小於緩衝陣列的長度。*/
}fr1.close();fw1.close();
long e = System.currentTimeMillis();
System.out.println("複製檔案共耗時:"+(e-s)+" 毫秒");//複製檔案共耗時:2毫秒
}