您好,登錄后才能下訂單哦!
java的讀寫操作是學(xué)java開發(fā)的必經(jīng)之路,下面就來總結(jié)下java的讀寫操作。
從上圖可以開出,java的讀寫操作(輸入輸出)可以用“流”這個概念來表示,總體而言,java的讀寫操作又分為兩種:字符流和字節(jié)流。
什么是流?
流是一個抽象的概念。當(dāng)Java程序需要從數(shù)據(jù)源讀取數(shù)據(jù)時,會開啟一個到數(shù)據(jù)源的流。數(shù)據(jù)源可以是文件,內(nèi)存或者網(wǎng)絡(luò)等。同樣,當(dāng)程序需要輸出數(shù)據(jù)到目的地時也一樣會開啟一個流,數(shù)據(jù)目的地也可以是文件、內(nèi)存或者網(wǎng)絡(luò)等。流的創(chuàng)建是為了更方便地處理數(shù)據(jù)的輸入輸出。
那么字節(jié)流和字符流又有什么區(qū)別呢?
1.字節(jié)流也稱為原始數(shù)據(jù),需要用戶讀入后進行相應(yīng)的編碼轉(zhuǎn)換。而字符流的實現(xiàn)是基于自動轉(zhuǎn)換的,讀取數(shù)據(jù)時會把數(shù)據(jù)按照J(rèn)VM的默認(rèn)編碼自動轉(zhuǎn)換成字符。
2.字符流處理的單元為2個字節(jié)的Unicode字符,分別操作字符、字符數(shù)組或字符串,而字節(jié)流處理單元為1個字節(jié),操作字節(jié)和字節(jié)數(shù)組。
所以字符流是由Java虛擬機將字節(jié)轉(zhuǎn)化為2個字節(jié)的Unicode字符為單位的字符而成的。
3.字節(jié)流可用于任何類型的對象,包括二進制對象,而字符流只能處理字符或者字符串,字節(jié)流提供了處理任何類型的IO操作的功能,但它不能直接處理Unicode字符,而字符流就可以;
基于以上的區(qū)別,那么什么情況下用字符流,什么情況下用字節(jié)流呢?
如果是音頻文件、圖片、歌曲,就用字節(jié)流好點;如果是中文(文本)的,用字符流更好;
說了這么多,字節(jié)流和字符流處理文件到底怎么用呢?
稍安勿躁,讓我們先來看看在java中,輸入輸出操作的步驟是什么?
1 使用File類打開一個文件
2 通過字節(jié)流或字符流的子類,指定輸出的位置,注,
3 進行讀/寫操作
4 關(guān)閉輸入/輸出
IO操作屬于資源操作,一定要記得關(guān)閉
字節(jié)流:
1.按照字節(jié)流的方式從文件中讀取數(shù)據(jù)。
2.package ioInJava.characterStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class CharIo {
public static void main(String[] args) {
// 第一種方式讀文件,因為方法throws了異常,所以在這要捕獲異常
try {
CharIo.readFromFileByByte();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("找不到文件啊");
} catch (IOException e) {
e.printStackTrace();
System.out.println("讀不成功??!");
}
System.out.println("===========================");
// 第二種方式讀文件
try {
CharIo.readFromFileByteTwo();
} catch (IOException e) {
e.printStackTrace();
System.out.println("還是讀不成功啊!");
}
}
/**
* 第一種方法讀文件
* 通過字符流讀取文件中的數(shù)據(jù)
* @throws IOException
*/
public static void readFromFileByByte() throws IOException{
File file = new File("abc.txt");
// 如果文件不存在則創(chuàng)建文件
if (!file.exists()) {
file.createNewFile();
}
InputStream inputStream = new FileInputStream(file);
// 這里定義了數(shù)組的長度是1024個字節(jié),如果文件超出這字節(jié),就會溢出,結(jié)果就是讀不到1024字節(jié)以后的東西
byte[] bs = new byte[1024];
// 這里len獲得的是文件中內(nèi)容的長度
int len = inputStream.read(bs);
inputStream.close();
System.out.println(new String(bs));
}
/**
* 第二種方法讀文件
* 通過字符流讀取文件中的數(shù)據(jù)
* @throws IOException
*/
public static void readFromFileByteTwo() throws IOException{
// 注意這里的不同,F(xiàn)ile.separator是分隔符,這里指明絕對路徑,即D盤根目錄下的abc.txt文件
File file = new File("d:" + File.separator+"abc.txt");
// 如果文件不存在則創(chuàng)建文件
if (!file.exists()) {
file.createNewFile();
}
InputStream inputStream = new FileInputStream(file);
// 這里也有不同,可以根據(jù)文件的大小來聲明byte數(shù)組的大小,確保能把文件讀完
byte[] bs = new byte[(int)file.length()];
// read()方法每次只能讀一個byte的內(nèi)容
inputStream.read(bs);
inputStream.close();
System.out.println(new String(bs));
}
}
2.按照字節(jié)流的方式向文件中寫入數(shù)據(jù)。
3.package ioInJava.byteStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
@author wsg
*/
public class WriteToFile {
public static void main(String[] args) {
File file = new File("D:"+File.separator+"write.doc");
OutputStream outputStream = null;
if (!file.exists()) {
try {
// 如果文件找不到,就new一個
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
// 定義輸出流,寫入文件的流
outputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 定義將要寫入文件的數(shù)據(jù)
String string = "Hell Java, Hello World, 你好,世界!";
// 把string轉(zhuǎn)換成byte型的,并存放在數(shù)組中
byte[] bs = string.getBytes();
try {
// 寫入bs中的數(shù)據(jù)到file中
outputStream.write(bs);
} catch (IOException e) {
e.printStackTrace();
}
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// =================到此,文件的寫入已經(jīng)完成了!
// 如果想在文件后面追加內(nèi)容的話,用下面的方法
OutputStream outToFileEnd = null;
try {
outToFileEnd = new FileOutputStream(file,true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {// 這里利用了finally總會被執(zhí)行的特性,索性把后面的代碼都寫在finally中
String string2 = "Here I come!!";
byte[] bs2 = string2.getBytes();
try {
outToFileEnd.write(bs2);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
outToFileEnd.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
1.初學(xué)者一般很容易搞混,或者弄不清inputstream和outpustream到底哪個是讀數(shù)據(jù),哪個是寫數(shù)據(jù),這里要說明的是,“讀和寫”是相對于程序本身而言的,主要記清楚一點即可,那就是凡是需要提供給程序處理的數(shù)據(jù)就是輸入數(shù)據(jù),當(dāng)然就是inputstream,這里的in是要in到程序里面去,那么數(shù)據(jù)從哪里來呢,自然是從外界(網(wǎng)絡(luò),內(nèi)存或者文件),那么針對文件而言,inputstream就是讀文件了。反之,凡是程序已經(jīng)處理過的數(shù)據(jù),當(dāng)然要流出程序啦,那就是out咯,所以outputstream就是輸出的,那么從程序中流出,只能到外界(網(wǎng)絡(luò)、內(nèi)存或者文件),針對文件而言,就是寫操作啦!(同樣的道理可以針對字符流的操作)
【簡言之,針對程序而言,in是入,out是出;這對文件而言,in是讀,out是寫!】
2.inputstream和OutputStream都是抽象類,不能實例化,使用時必須實例化一個子類(其中FileInputStream和FileOutputStream使用最多)對象來進行相關(guān)操作。
3.InputStream inputStream = new FileInputStream(fileName);當(dāng)使用這個命令時,系統(tǒng)會提示有異常拋出,因為我們上面定義的文件程序認(rèn)為是有可能存在,有可能不存在的,所以在eclipse中,給出了兩個解決辦法,一個是直接拋出異常聲明,由系統(tǒng)自己解決;另一個是用try,catch結(jié)構(gòu)處理異常!
4.3.按照字符流的方式向文件中寫入數(shù)據(jù)。
5.package ioInJava.characterStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
public class CharIo {
public static void main(String[] args) throws IOException {
// 定義一個d盤根目錄下的test文檔,F(xiàn)ile.separator是分隔符
// 下面這句代碼,就算原本沒有這個文件,也會在對應(yīng)的目錄創(chuàng)建一個文件
File file = new File("D:" + File.separator + "test.docx");
// 下面這也會拋出異常,這次我們?yōu)榱舜a結(jié)構(gòu)清晰起見,直接throw給main吧
Writer writer = new FileWriter(file);
String string = "今天是教師節(jié)!";
writer.write(string);
// 在這一定要記得關(guān)閉流
writer.close();
}
}
但是,上面的代碼有一個問題,比如,載定義一個string2,再次調(diào)用writer.write(string2)方法的時候,會發(fā)現(xiàn)test文件中的內(nèi)容會被string2的內(nèi)容覆蓋,要想實現(xiàn)內(nèi)容追加到文件尾部,代碼如下,其實就是小小的修改,利用它的一個方法!
package ioInJava.characterStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
public class CharIo {
public static void main(String[] args) throws IOException {
// 定義一個d盤根目錄下的test文檔,F(xiàn)ile.separator是分隔符
// 下面這句代碼,就算原本沒有這個文件,也會在對應(yīng)的目錄創(chuàng)建一個文件
File file = new File("D:" + File.separator + "test.docx");
// 下面這也會拋出異常,這次我們?yōu)榱舜a結(jié)構(gòu)清晰起見,直接throw給main吧
// 這里改變了writer的類型,變成了追加型
Writer writer = new FileWriter(file, true);
String string = "今天是教師節(jié)!";
writer.write(string);
String string2 = "祝愿所有的老師教師節(jié)快樂!";
writer.write(string2);;
// 在這一定要記得關(guān)閉流
writer.close();
}
}
4.按照字符流的方式從文件中讀取數(shù)據(jù)。
package ioInJava.characterStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
public class ReadFromFile {
public static void main(String[] args) throws IOException {
File file = new File("d:" + File.separator + "test.docx");
Reader reader = new FileReader(file);
char[] cs= new char[1024];
// 上面定義了一個大小為1024的char型數(shù)組,如果文件內(nèi)容過大,程序就會報錯,而不是只讀到1024的大小
reader.read(cs, 0, (int)file.length());
System.out.println(cs);
reader.close();
}
}
上面的代碼只能讀取內(nèi)容不超過1024字符的內(nèi)容,這顯然不是我們想要的,如何讀取一個任意大小的文件呢!那么最簡單的方法就是加大數(shù)組的空間大小了,可以用file.length獲取文件的大小,從而定義數(shù)組的大??!char[] cs= new char[(int)file.length()];
當(dāng)然,這不是最好的辦法,請看下面的代碼:
package ioInJava.characterStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class ReadFromFile {
public static void main(String[] args) throws IOException {
try {
// 聲明一個可變長的stringBuffer對象
StringBuffer sb = new StringBuffer("");
/*
* 讀取完整文件
*/
Reader reader = new FileReader("d:" + File.separator + "test.docx");
// 這里我們用到了字符操作的BufferedReader類
BufferedReader bufferedReader = new BufferedReader(reader);
String string = null;
// 按行讀取,結(jié)束的判斷是是否為null,按字節(jié)或者字符讀取時結(jié)束的標(biāo)志是-1
while ((string = bufferedReader.readLine()) != null) {
// 這里我們用到了StringBuffer的append方法,這個比string的“+”要高效
sb.append(string + "/n");
System.out.println(string);
}
// 注意這兩個關(guān)閉的順序
bufferedReader.close();
reader.close();
/*
* 完整寫入文件
*/
Writer writer = new FileWriter("d:" + File.separator + "test2.docx");
BufferedWriter bw = new BufferedWriter(writer);
// 注意這里調(diào)用了toString方法
bw.write(sb.toString());
// 注意這兩個關(guān)閉的順序
bw.close();
writer.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。