javaIO整理
寫(xiě)在前面:本文章基本覆蓋了java IO的全部?jī)?nèi)容,java新IO沒(méi)有涉及,因?yàn)槲蚁牒瓦@個(gè)分開(kāi),以突出那個(gè)的重要性,新IO哪一篇文章還沒(méi)有開(kāi)始寫(xiě),估計(jì)很快就能和大家見(jiàn)面。照舊,文章依舊以例子為主,因?yàn)橹v解內(nèi)容的java書(shū)很多了,我覺(jué)的學(xué)以致用才是真。代碼是寫(xiě)出來(lái)的,不是看出來(lái)的。
最后歡迎大家提出意見(jiàn)和建議。
【案例1】創(chuàng)建一個(gè)新文件
import java.io.*; class hello{public static void main(String[] args) {File f=new File("D:\\hello.txt");try{f.createNewFile();}catch (Exception e) {e.printStackTrace();}} }【運(yùn)行結(jié)果】:
程序運(yùn)行之后,在d盤下會(huì)有一個(gè)名字為hello.txt的文件。
【案例2】File類的兩個(gè)常量
import java.io.*; class hello{public static void main(String[] args) {System.out.println(File.separator);System.out.println(File.pathSeparator);} }?【運(yùn)行結(jié)果】:
\
;
此處多說(shuō)幾句:有些同學(xué)可能認(rèn)為,我直接在windows下使用\進(jìn)行分割不行嗎?當(dāng)然是可以的。但是在linux下就不是\了。所以,要想使得我們的代碼跨平臺(tái),更加健壯,所以,大家都采用這兩個(gè)常量吧,其實(shí)也多寫(xiě)不了幾行。呵呵、
現(xiàn)在我們使用File類中的常量改寫(xiě)上面的代碼:
?
import java.io.*; class hello{public static void main(String[] args) {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);try{f.createNewFile();}catch (Exception e) {e.printStackTrace();}} }?所以建議使用File類中的常量。?
刪除一個(gè)文件
?
/*** 刪除一個(gè)文件* */ import java.io.*; class hello{public static void main(String[] args) {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);if(f.exists()){f.delete();}else{System.out.println("文件不存在");}} }?創(chuàng)建一個(gè)文件夾
?
/*** 創(chuàng)建一個(gè)文件夾* */ import java.io.*; class hello{public static void main(String[] args) {String fileName="D:"+File.separator+"hello";File f=new File(fileName);f.mkdir();} }【運(yùn)行結(jié)果】:
?
D盤下多了一個(gè)hello文件夾
列出指定目錄的全部文件(包括隱藏文件):
/*** 使用list列出指定目錄的全部文件* */ import java.io.*; class hello{public static void main(String[] args) {String fileName="D:"+File.separator;File f=new File(fileName);String[] str=f.list();for (int i = 0; i < str.length; i++) {System.out.println(str[i]);}} }【運(yùn)行結(jié)果】:
?
$RECYCLE.BIN
?
360
?
360Downloads
?
360Rec
?
360SoftMove
?
Config.Msi
?
da
?
Downloads
?
DriversBackup
?
eclipse
?
java web整合開(kāi)發(fā)和項(xiàng)目實(shí)戰(zhàn)
?
Lenovo
?
MSOCache
?
Program
?
Program Files
?
python
?
RECYGLER.{8F92DA15-A229-A4D5-B5CE-5280C8B89C19}
?
System Volume Information
?
Tomcat6
?
var
?
vod_cache_data
?
新建文件夾
?
(你的運(yùn)行結(jié)果應(yīng)該和這個(gè)不一樣的,呵呵)
?
但是使用list返回的是String數(shù)組,。而且列出的不是完整路徑,如果想列出完整路徑的話,需要使用listFiles.他返回的是File的數(shù)組
列出指定目錄的全部文件(包括隱藏文件):
/*** 使用listFiles列出指定目錄的全部文件* listFiles輸出的是完整路徑* */ import java.io.*; class hello{public static void main(String[] args) {String fileName="D:"+File.separator;File f=new File(fileName);File[] str=f.listFiles();for (int i = 0; i < str.length; i++) {System.out.println(str[i]);}} }?【運(yùn)行結(jié)果】:
?
D:\$RECYCLE.BIN
?
D:\360
?
D:\360Downloads
?
D:\360Rec
?
D:\360SoftMove
?
D:\Config.Msi
?
D:\da
?
D:\Downloads
?
D:\DriversBackup
?
D:\eclipse
?
D:\java web整合開(kāi)發(fā)和項(xiàng)目實(shí)戰(zhàn)
?
D:\Lenovo
?
D:\MSOCache
?
D:\Program
?
D:\Program Files
?
D:\python
?
D:\RECYGLER.{8F92DA15-A229-A4D5-B5CE-5280C8B89C19}
?
D:\System Volume Information
?
D:\Tomcat6
?
D:\var
?
D:\vod_cache_data
?
D:\新建文件夾
?
通過(guò)比較可以指定,使用listFiles更加方便、
判斷一個(gè)指定的路徑是否為目錄
/*** 使用isDirectory判斷一個(gè)指定的路徑是否為目錄* */ import java.io.*; class hello{public static void main(String[] args) {String fileName="D:"+File.separator;File f=new File(fileName);if(f.isDirectory()){System.out.println("YES");}else{System.out.println("NO");}} }【運(yùn)行結(jié)果】:YES
搜索指定目錄的全部?jī)?nèi)容
?
/*** 列出指定目錄的全部?jī)?nèi)容* */ import java.io.*; class hello{public static void main(String[] args) {String fileName="D:"+File.separator;File f=new File(fileName);print(f);}public static void print(File f){if(f!=null){if(f.isDirectory()){File[] fileArray=f.listFiles();if(fileArray!=null){for (int i = 0; i < fileArray.length; i++) {//遞歸調(diào)用 print(fileArray[i]);}}}else{System.out.println(f);}}} }【運(yùn)行結(jié)果】:
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\framepages\web4welcome_jsp.java
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\help_005fhome_jsp.class
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\help_005fhome_jsp.java
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\home_jsp.class
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\home_jsp.java
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\index_jsp.class
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\index_jsp.java
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\login_jsp.class
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\login_jsp.java
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\modify_005fuser_005finfo_jsp.class
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\modify_005fuser_005finfo_jsp.java
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\register_005fnotify_jsp.class
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\register_005fnotify_jsp.java
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\sign_005fup_jsp.class
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\sign_005fup_jsp.java
?
D:\Tomcat6\work\Catalina\localhost\nevel\org\apache\jsp\transit_jsp.class
?
……
?
【使用RandomAccessFile寫(xiě)入文件】
?
/*** 使用RandomAccessFile寫(xiě)入文件* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);RandomAccessFile demo=new RandomAccessFile(f,"rw");demo.writeBytes("asdsad");demo.writeInt(12);demo.writeBoolean(true);demo.writeChar('A');demo.writeFloat(1.21f);demo.writeDouble(12.123);demo.close(); } }如果你此時(shí)打開(kāi)hello.txt查看的話,會(huì)發(fā)現(xiàn)那是亂碼。
字節(jié)流
【向文件中寫(xiě)入字符串】
/*** 字節(jié)流* 向文件中寫(xiě)入字符串* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);OutputStream out =new FileOutputStream(f);String str="你好";byte[] b=str.getBytes();out.write(b);out.close();} }查看hello.txt會(huì)看到“你好”
當(dāng)然也可以一個(gè)字節(jié)一個(gè)字節(jié)的寫(xiě):
/*** 字節(jié)流* 向文件中一個(gè)字節(jié)一個(gè)字節(jié)的寫(xiě)入字符串* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);OutputStream out =new FileOutputStream(f);String str="你好";byte[] b=str.getBytes();for (int i = 0; i < b.length; i++) {out.write(b[i]);}out.close();} }結(jié)果還是:“你好”
向文件中追加新內(nèi)容:
/*** 字節(jié)流* 向文件中追加新內(nèi)容:* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);OutputStream out =new FileOutputStream(f,true);String str="Rollen";//String str="\r\nRollen"; 可以換行byte[] b=str.getBytes();for (int i = 0; i < b.length; i++) {out.write(b[i]);}out.close();} }?【運(yùn)行結(jié)果】:
你好Rollen
【讀取文件內(nèi)容】
/*** 字節(jié)流* 讀文件內(nèi)容* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);InputStream in=new FileInputStream(f);byte[] b=new byte[1024];in.read(b);in.close();System.out.println(new String(b));} }【運(yùn)行結(jié)果】
你好Rollen
Rollen_
但是這個(gè)例子讀取出來(lái)會(huì)有大量的空格,我們可以利用in.read(b);的返回值來(lái)設(shè)計(jì)程序。如下:
/*** 字節(jié)流* 讀文件內(nèi)容* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);InputStream in=new FileInputStream(f);byte[] b=new byte[1024];int len=in.read(b);in.close();System.out.println("讀入長(zhǎng)度為:"+len);System.out.println(new String(b,0,len));} }【運(yùn)行結(jié)果】:
讀入長(zhǎng)度為:18
你好Rollen
Rollen
讀者觀察上面的例子可以看出,我們預(yù)先申請(qǐng)了一個(gè)指定大小的空間,但是有時(shí)候這個(gè)空間可能太小,有時(shí)候可能太大,我們需要準(zhǔn)確的大小,這樣節(jié)省空間,那么我們可以這樣干:
?
/*** 字節(jié)流* 讀文件內(nèi)容,節(jié)省空間* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);InputStream in=new FileInputStream(f);byte[] b=new byte[(int)f.length()];in.read(b);System.out.println("文件長(zhǎng)度為:"+f.length());in.close();System.out.println(new String(b));} }文件長(zhǎng)度為:18
你好Rollen
Rollen
將上面的例子改為一個(gè)一個(gè)讀:
?
/*** 字節(jié)流* 讀文件內(nèi)容,節(jié)省空間* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);InputStream in=new FileInputStream(f);byte[] b=new byte[(int)f.length()];for (int i = 0; i < b.length; i++) {b[i]=(byte)in.read();}in.close();System.out.println(new String(b));} }?輸出的結(jié)果和上面的一樣。
細(xì)心的讀者可能會(huì)發(fā)現(xiàn),上面的幾個(gè)例子都是在知道文件的內(nèi)容多大,然后才展開(kāi)的,有時(shí)候我們不知道文件有多大,這種情況下,我們需要判斷是否獨(dú)到文件的末尾。
/*** 字節(jié)流*讀文件* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);InputStream in=new FileInputStream(f);byte[] b=new byte[1024];int count =0;int temp=0;while((temp=in.read())!=(-1)){b[count++]=(byte)temp;}in.close();System.out.println(new String(b));} }【運(yùn)行結(jié)果】
你好Rollen
Rollen_
提醒一下,當(dāng)獨(dú)到文件末尾的時(shí)候會(huì)返回-1.正常情況下是不會(huì)返回-1的
字符流
【向文件中寫(xiě)入數(shù)據(jù)】
現(xiàn)在我們使用字符流
/*** 字符流* 寫(xiě)入數(shù)據(jù)* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);Writer out =new FileWriter(f);String str="hello";out.write(str);out.close();} }當(dāng)你打開(kāi)hello.txt的時(shí)候,會(huì)看到hello
其實(shí)這個(gè)例子上之前的例子沒(méi)什么區(qū)別,只是你可以直接輸入字符串,而不需要你將字符串轉(zhuǎn)化為字節(jié)數(shù)組。
當(dāng)你如果想問(wèn)文件中追加內(nèi)容的時(shí)候,可以使用將上面的聲明out的哪一行換為:
Writer out =new FileWriter(f,true);這樣,當(dāng)你運(yùn)行程序的時(shí)候,會(huì)發(fā)現(xiàn)文件內(nèi)容變?yōu)?#xff1a;
hellohello
如果想在文件中換行的話,需要使用“\r\n”
比如將str變?yōu)镾tring str="\r\nhello";
這樣文件追加的str的內(nèi)容就會(huì)換行了。
從文件中讀內(nèi)容:
/*** 字符流* 從文件中讀出內(nèi)容* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);char[] ch=new char[100];Reader read=new FileReader(f);int count=read.read(ch);read.close();System.out.println("讀入的長(zhǎng)度為:"+count);System.out.println("內(nèi)容為"+new String(ch,0,count));} }【運(yùn)行結(jié)果】:
?
讀入的長(zhǎng)度為:17
?
內(nèi)容為hellohello
?
hello
當(dāng)然最好采用循環(huán)讀取的方式,因?yàn)槲覀冇袝r(shí)候不知道文件到底有多大。
?
/*** 字符流* 從文件中讀出內(nèi)容* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName="D:"+File.separator+"hello.txt";File f=new File(fileName);char[] ch=new char[100];Reader read=new FileReader(f);int temp=0;int count=0;while((temp=read.read())!=(-1)){ch[count++]=(char)temp;}read.close();System.out.println("內(nèi)容為"+new String(ch,0,count));} }運(yùn)行結(jié)果:
?
內(nèi)容為hellohello
hello
關(guān)于字節(jié)流和字符流的區(qū)別
?
實(shí)際上字節(jié)流在操作的時(shí)候本身是不會(huì)用到緩沖區(qū)的,是文件本身的直接操作的,但是字符流在操作的?時(shí)候下后是會(huì)用到緩沖區(qū)的,是通過(guò)緩沖區(qū)來(lái)操作文件的。
?
讀者可以試著將上面的字節(jié)流和字符流的程序的最后一行關(guān)閉文件的代碼注釋掉,然后運(yùn)行程序看看。你就會(huì)發(fā)現(xiàn)使用字節(jié)流的話,文件中已經(jīng)存在內(nèi)容,但是使用字符流的時(shí)候,文件中還是沒(méi)有內(nèi)容的,這個(gè)時(shí)候就要刷新緩沖區(qū)。
?
使用字節(jié)流好還是字符流好呢?
?
答案是字節(jié)流。首先因?yàn)橛脖P上的所有文件都是以字節(jié)的形式進(jìn)行傳輸或者保存的,包括圖片等內(nèi)容。但是字符只是在內(nèi)存中才會(huì)形成的,所以在開(kāi)發(fā)中,字節(jié)流使用廣泛。
?
文件的復(fù)制
?
其實(shí)DOS下就有一個(gè)文件復(fù)制功能,比如我們想把d盤下面的hello.txt文件復(fù)制到d盤下面的rollen.txt文件中,那么我們就可以使用下面的命令:
?
copy d:\hello.txt d:\rollen.txt
運(yùn)行之后你會(huì)在d盤中看見(jiàn)hello.txt.,并且兩個(gè)文件的內(nèi)容是一樣的,(這是屁話)
下面我們使用程序來(lái)復(fù)制文件吧。
?
基本思路還是從一個(gè)文件中讀入內(nèi)容,邊讀邊寫(xiě)入另一個(gè)文件,就是這么簡(jiǎn)單。、
?
首先編寫(xiě)下面的代碼:
/*** 文件的復(fù)制* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {if(args.length!=2){System.out.println("命令行參數(shù)輸入有誤,請(qǐng)檢查");System.exit(1);}File file1=new File(args[0]);File file2=new File(args[1]);if(!file1.exists()){System.out.println("被復(fù)制的文件不存在");System.exit(1);}InputStream input=new FileInputStream(file1);OutputStream output=new FileOutputStream(file2);if((input!=null)&&(output!=null)){int temp=0;while((temp=input.read())!=(-1)){output.write(temp);}}input.close();output.close(); } }然后在命令行下面
javac hello.java
java hello d:\hello.txt d:\rollen.txt
現(xiàn)在你就會(huì)在d盤看到rollen.txt了,
OutputStreramWriter?和InputStreamReader類
?
整個(gè)IO類中除了字節(jié)流和字符流還包括字節(jié)和字符轉(zhuǎn)換流。
?
OutputStreramWriter將輸出的字符流轉(zhuǎn)化為字節(jié)流
?
InputStreamReader將輸入的字節(jié)流轉(zhuǎn)換為字符流
?
但是不管如何操作,最后都是以字節(jié)的形式保存在文件中的。
將字節(jié)輸出流轉(zhuǎn)化為字符輸出流
?
/*** 將字節(jié)輸出流轉(zhuǎn)化為字符輸出流* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName= "d:"+File.separator+"hello.txt";File file=new File(fileName);Writer out=new OutputStreamWriter(new FileOutputStream(file));out.write("hello");out.close();} }運(yùn)行結(jié)果:文件中內(nèi)容為:hello
?
將字節(jié)輸入流變?yōu)樽址斎肓?/h4> /*** 將字節(jié)輸入流變?yōu)樽址斎肓? */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String fileName= "d:"+File.separator+"hello.txt";File file=new File(fileName);Reader read=new InputStreamReader(new FileInputStream(file));char[] b=new char[100];int len=read.read(b);System.out.println(new String(b,0,len));read.close();} }
【運(yùn)行結(jié)果】:hello
?
前面列舉的輸出輸入都是以文件進(jìn)行的,現(xiàn)在我們以內(nèi)容為輸出輸入目的地,使用內(nèi)存操作流
?
ByteArrayInputStream?主要將內(nèi)容寫(xiě)入內(nèi)容
?
ByteArrayOutputStream??主要將內(nèi)容從內(nèi)存輸出
?
使用內(nèi)存操作流將一個(gè)大寫(xiě)字母轉(zhuǎn)化為小寫(xiě)字母
?
/*** 使用內(nèi)存操作流將一個(gè)大寫(xiě)字母轉(zhuǎn)化為小寫(xiě)字母* */ import java.io.*; class hello{public static void main(String[] args) throws IOException {String str="ROLLENHOLT";ByteArrayInputStream input=new ByteArrayInputStream(str.getBytes());ByteArrayOutputStream output=new ByteArrayOutputStream();int temp=0;while((temp=input.read())!=-1){char ch=(char)temp;output.write(Character.toLowerCase(ch));}String outStr=output.toString();input.close();output.close();System.out.println(outStr);} }【運(yùn)行結(jié)果】:
?
rollenholt
?
內(nèi)容操作流一般使用來(lái)生成一些臨時(shí)信息采用的,這樣可以避免刪除的麻煩。
?
管道流
?
管道流主要可以進(jìn)行兩個(gè)線程之間的通信。
?
PipedOutputStream?管道輸出流
?
PipedInputStream?管道輸入流
驗(yàn)證管道流
/*** 驗(yàn)證管道流* */ import java.io.*;/*** 消息發(fā)送類* */ class Send implements Runnable{private PipedOutputStream out=null;public Send() {out=new PipedOutputStream();}public PipedOutputStream getOut(){return this.out;}public void run(){String message="hello , Rollen";try{out.write(message.getBytes());}catch (Exception e) {e.printStackTrace();}try{out.close();}catch (Exception e) {e.printStackTrace();}} }/*** 接受消息類* */ class Recive implements Runnable{private PipedInputStream input=null;public Recive(){this.input=new PipedInputStream();}public PipedInputStream getInput(){return this.input;}public void run(){byte[] b=new byte[1000];int len=0;try{len=this.input.read(b);}catch (Exception e) {e.printStackTrace();}try{input.close();}catch (Exception e) {e.printStackTrace();}System.out.println("接受的內(nèi)容為 "+(new String(b,0,len)));} } /*** 測(cè)試類* */ class hello{public static void main(String[] args) throws IOException {Send send=new Send();Recive recive=new Recive();try{ //管道連接 send.getOut().connect(recive.getInput());}catch (Exception e) {e.printStackTrace();}new Thread(send).start();new Thread(recive).start();} }【運(yùn)行結(jié)果】:
?
接受的內(nèi)容為?hello , Rollen
?
打印流
?
/*** 使用PrintStream進(jìn)行輸出* */ import java.io.*;class hello {public static void main(String[] args) throws IOException {PrintStream print = new PrintStream(new FileOutputStream(new File("d:"+ File.separator + "hello.txt")));print.println(true);print.println("Rollen");print.close();} }?【運(yùn)行結(jié)果】:
?
true
?
Rollen
?
當(dāng)然也可以格式化輸出
/*** 使用PrintStream進(jìn)行輸出* 并進(jìn)行格式化* */ import java.io.*; class hello {public static void main(String[] args) throws IOException {PrintStream print = new PrintStream(new FileOutputStream(new File("d:"+ File.separator + "hello.txt")));String name="Rollen";int age=20;print.printf("姓名:%s. 年齡:%d.",name,age);print.close();} }?【運(yùn)行結(jié)果】:
姓名:Rollen.?年齡:20.
使用OutputStream向屏幕上輸出內(nèi)容
?
/*** 使用OutputStream向屏幕上輸出內(nèi)容 * */ import java.io.*; class hello {public static void main(String[] args) throws IOException {OutputStream out=System.out;try{out.write("hello".getBytes());}catch (Exception e) {e.printStackTrace();}try{out.close();}catch (Exception e) {e.printStackTrace();}} }?【運(yùn)行結(jié)果】:
?
hello
輸入輸出重定向
?
import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream;/*** 為System.out.println()重定向輸出* */ public class systemDemo{public static void main(String[] args){// 此刻直接輸出到屏幕System.out.println("hello");File file = new File("d:" + File.separator + "hello.txt");try{System.setOut(new PrintStream(new FileOutputStream(file)));}catch(FileNotFoundException e){e.printStackTrace();}System.out.println("這些內(nèi)容在文件中才能看到哦!");} }【運(yùn)行結(jié)果】:
eclipse的控制臺(tái)輸出的是hello。然后當(dāng)我們查看d盤下面的hello.txt文件的時(shí)候,會(huì)在里面看到:這些內(nèi)容在文件中才能看到哦!
import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream;/*** System.err重定向 這個(gè)例子也提示我們可以使用這種方法保存錯(cuò)誤信息* */ public class systemErr{public static void main(String[] args){File file = new File("d:" + File.separator + "hello.txt");System.err.println("這些在控制臺(tái)輸出");try{System.setErr(new PrintStream(new FileOutputStream(file)));}catch(FileNotFoundException e){e.printStackTrace();}System.err.println("這些在文件中才能看到哦!");} }?【運(yùn)行結(jié)果】:
你會(huì)在eclipse的控制臺(tái)看到紅色的輸出:“這些在控制臺(tái)輸出”,然后在d盤下面的hello.txt中會(huì)看到:這些在文件中才能看到哦!
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;/*** System.in重定向* */ public class systemIn{public static void main(String[] args){File file = new File("d:" + File.separator + "hello.txt");if(!file.exists()){return;}else{try{System.setIn(new FileInputStream(file));}catch(FileNotFoundException e){e.printStackTrace();}byte[] bytes = new byte[1024];int len = 0;try{len = System.in.read(bytes);}catch(IOException e){e.printStackTrace();}System.out.println("讀入的內(nèi)容為:" + new String(bytes, 0, len));}} }?【運(yùn)行結(jié)果】:
?
前提是我的d盤下面的hello.txt中的內(nèi)容是:“這些文件中的內(nèi)容哦!”,然后運(yùn)行程序,輸出的結(jié)果為:讀入的內(nèi)容為:這些文件中的內(nèi)容哦!
BufferedReader的小例子
?
注意:?BufferedReader只能接受字符流的緩沖區(qū),因?yàn)槊恳粋€(gè)中文需要占據(jù)兩個(gè)字節(jié),所以需要將System.in這個(gè)字節(jié)輸入流變?yōu)樽址斎肓?#xff0c;采用:
?
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));下面給一個(gè)實(shí)例:
?
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;/*** 使用緩沖區(qū)從鍵盤上讀入內(nèi)容* */ public class BufferedReaderDemo{public static void main(String[] args){BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));String str = null;System.out.println("請(qǐng)輸入內(nèi)容");try{str = buf.readLine();}catch(IOException e){e.printStackTrace();}System.out.println("你輸入的內(nèi)容是:" + str);} }運(yùn)行結(jié)果:
?
請(qǐng)輸入內(nèi)容
?
dasdas
?
你輸入的內(nèi)容是:dasdas
Scanner類
?
其實(shí)我們比較常用的是采用Scanner類來(lái)進(jìn)行數(shù)據(jù)輸入,下面來(lái)給一個(gè)Scanner的例子吧
import java.util.Scanner;/*** Scanner的小例子,從鍵盤讀數(shù)據(jù)* */ public class ScannerDemo{public static void main(String[] args){Scanner sca = new Scanner(System.in);// 讀一個(gè)整數(shù)int temp = sca.nextInt();System.out.println(temp);//讀取浮點(diǎn)數(shù)float flo=sca.nextFloat();System.out.println(flo);//讀取字符//...等等的,都是一些太基礎(chǔ)的,就不師范了。 } }其實(shí)Scanner可以接受任何的輸入流
?
下面給一個(gè)使用Scanner類從文件中讀出內(nèi)容
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner;/*** Scanner的小例子,從文件中讀內(nèi)容* */ public class ScannerDemo{public static void main(String[] args){File file = new File("d:" + File.separator + "hello.txt");Scanner sca = null;try{sca = new Scanner(file);}catch(FileNotFoundException e){e.printStackTrace();}String str = sca.next();System.out.println("從文件中讀取的內(nèi)容是:" + str);} }【運(yùn)行結(jié)果】:
?
從文件中讀取的內(nèi)容是:這些文件中的內(nèi)容哦!
?
數(shù)據(jù)操作流DataOutputStream、DataInputStream類
?
import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException;public class DataOutputStreamDemo{public static void main(String[] args) throws IOException{File file = new File("d:" + File.separator + "hello.txt");char[] ch = { 'A', 'B', 'C' };DataOutputStream out = null;out = new DataOutputStream(new FileOutputStream(file));for(char temp : ch){out.writeChar(temp);}out.close();} }?A B C
?
現(xiàn)在我們?cè)谏厦胬拥幕A(chǔ)上,使用DataInputStream讀出內(nèi)容
?
import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException;public class DataOutputStreamDemo{public static void main(String[] args) throws IOException{File file = new File("d:" + File.separator + "hello.txt");DataInputStream input = new DataInputStream(new FileInputStream(file));char[] ch = new char[10];int count = 0;char temp;while((temp = input.readChar()) != 'C'){ch[count++] = temp;}System.out.println(ch);} }【運(yùn)行結(jié)果】:
?
AB
?
合并流?SequenceInputStream
?
SequenceInputStream主要用來(lái)將2個(gè)流合并在一起,比如將兩個(gè)txt中的內(nèi)容合并為另外一個(gè)txt。下面給出一個(gè)實(shí)例:
?
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.SequenceInputStream;/*** 將兩個(gè)文本文件合并為另外一個(gè)文本文件* */ public class SequenceInputStreamDemo{public static void main(String[] args) throws IOException{File file1 = new File("d:" + File.separator + "hello1.txt");File file2 = new File("d:" + File.separator + "hello2.txt");File file3 = new File("d:" + File.separator + "hello.txt");InputStream input1 = new FileInputStream(file1);InputStream input2 = new FileInputStream(file2);OutputStream output = new FileOutputStream(file3);// 合并流SequenceInputStream sis = new SequenceInputStream(input1, input2);int temp = 0;while((temp = sis.read()) != -1){output.write(temp);}input1.close();input2.close();output.close();sis.close();} }【運(yùn)行結(jié)果】
?
結(jié)果會(huì)在hello.txt文件中包含hello1.txt和hello2.txt文件中的內(nèi)容。
文件壓縮?ZipOutputStream類
先舉一個(gè)壓縮單個(gè)文件的例子吧:
?
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream;public class ZipOutputStreamDemo1{public static void main(String[] args) throws IOException{File file = new File("d:" + File.separator + "hello.txt");File zipFile = new File("d:" + File.separator + "hello.zip");InputStream input = new FileInputStream(file);ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));zipOut.putNextEntry(new ZipEntry(file.getName()));// 設(shè)置注釋zipOut.setComment("hello");int temp = 0;while((temp = input.read()) != -1){zipOut.write(temp);}input.close();zipOut.close();} }?【運(yùn)行結(jié)果】
?
運(yùn)行結(jié)果之前,我創(chuàng)建了一個(gè)hello.txt的文件,原本大小56個(gè)字節(jié),但是壓縮之后產(chǎn)生hello.zip之后,居然變成了175個(gè)字節(jié),有點(diǎn)搞不懂。
?
不過(guò)結(jié)果肯定是正確的,我只是提出我的一個(gè)疑問(wèn)而已。?
上面的這個(gè)例子測(cè)試的是壓縮單個(gè)文件,下面的們來(lái)看看如何壓縮多個(gè)文件。
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream;/*** 一次性壓縮多個(gè)文件* */ public class ZipOutputStreamDemo2{public static void main(String[] args) throws IOException{// 要被壓縮的文件夾File file = new File("d:" + File.separator + "temp");File zipFile = new File("d:" + File.separator + "zipFile.zip");InputStream input = null;ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));zipOut.setComment("hello");if(file.isDirectory()){File[] files = file.listFiles();for(int i = 0; i < files.length; ++i){input = new FileInputStream(files[i]);zipOut.putNextEntry(new ZipEntry(file.getName()+ File.separator + files[i].getName()));int temp = 0;while((temp = input.read()) != -1){zipOut.write(temp);}input.close();}}zipOut.close();} }【運(yùn)行結(jié)果】
?
先看看要被壓縮的文件吧:
接下來(lái)看看壓縮之后的:
大家自然想到,既然能壓縮,自然能解壓縮,在談解壓縮之前,我們會(huì)用到一個(gè)ZipFile類,先給一個(gè)這個(gè)例子吧。java中的每一個(gè)壓縮文件都是可以使用ZipFile來(lái)進(jìn)行表示的
import java.io.File; import java.io.IOException; import java.util.zip.ZipFile;/*** ZipFile演示* */ public class ZipFileDemo{public static void main(String[] args) throws IOException{File file = new File("d:" + File.separator + "hello.zip");ZipFile zipFile = new ZipFile(file);System.out.println("壓縮文件的名稱為:" + zipFile.getName());} }【運(yùn)行結(jié)果】:
?
壓縮文件的名稱為:d:\hello.zip
現(xiàn)在我們呢是時(shí)候來(lái)看看如何加壓縮文件了,和之前一樣,先讓我們來(lái)解壓?jiǎn)蝹€(gè)壓縮文件(也就是壓縮文件中只有一個(gè)文件的情況),我們采用前面的例子產(chǎn)生的壓縮文件hello.zip
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile;/*** 解壓縮文件(壓縮文件中只有一個(gè)文件的情況)* */ public class ZipFileDemo2{public static void main(String[] args) throws IOException{File file = new File("d:" + File.separator + "hello.zip");File outFile = new File("d:" + File.separator + "unZipFile.txt");ZipFile zipFile = new ZipFile(file);ZipEntry entry = zipFile.getEntry("hello.txt");InputStream input = zipFile.getInputStream(entry);OutputStream output = new FileOutputStream(outFile);int temp = 0;while((temp = input.read()) != -1){output.write(temp);}input.close();output.close();} }【運(yùn)行結(jié)果】:
?
解壓縮之前:
這個(gè)壓縮文件還是175字節(jié)
?
解壓之后產(chǎn)生:
?
又回到了56字節(jié),表示郁悶。
現(xiàn)在讓我們來(lái)解壓一個(gè)壓縮文件中包含多個(gè)文件的情況吧
?
ZipInputStream類
?
當(dāng)我們需要解壓縮多個(gè)文件的時(shí)候,ZipEntry就無(wú)法使用了,如果想操作更加復(fù)雜的壓縮文件,我們就必須使用ZipInputStream類
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream;/*** 解壓縮一個(gè)壓縮文件中包含多個(gè)文件的情況* */ public class ZipFileDemo3{public static void main(String[] args) throws IOException{File file = new File("d:" + File.separator + "zipFile.zip");File outFile = null;ZipFile zipFile = new ZipFile(file);ZipInputStream zipInput = new ZipInputStream(new FileInputStream(file));ZipEntry entry = null;InputStream input = null;OutputStream output = null;while((entry = zipInput.getNextEntry()) != null){System.out.println("解壓縮" + entry.getName() + "文件");outFile = new File("d:" + File.separator + entry.getName());if(!outFile.getParentFile().exists()){outFile.getParentFile().mkdir();}if(!outFile.exists()){outFile.createNewFile();}input = zipFile.getInputStream(entry);output = new FileOutputStream(outFile);int temp = 0;while((temp = input.read()) != -1){output.write(temp);}input.close();output.close();}} }?【運(yùn)行結(jié)果】:
?
被解壓的文件:
解壓之后再D盤下會(huì)出現(xiàn)一個(gè)temp文件夾,里面內(nèi)容:
?
PushBackInputStream回退流
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.PushbackInputStream;/*** 回退流操作* */ public class PushBackInputStreamDemo{public static void main(String[] args) throws IOException{String str = "hello,rollenholt";PushbackInputStream push = null;ByteArrayInputStream bat = null;bat = new ByteArrayInputStream(str.getBytes());push = new PushbackInputStream(bat);int temp = 0;while((temp = push.read()) != -1){if(temp == ','){push.unread(temp);temp = push.read();System.out.print("(回退" + (char) temp + ") ");}else{System.out.print((char) temp);}}} }【運(yùn)行結(jié)果】:
?
hello(回退,) rollenholt
?
/*** 取得本地的默認(rèn)編碼* */ public class CharSetDemo{public static void main(String[] args){System.out.println("系統(tǒng)默認(rèn)編碼為:" + System.getProperty("file.encoding"));} }【運(yùn)行結(jié)果】:
?
系統(tǒng)默認(rèn)編碼為:GBK
?
?
?
亂碼的產(chǎn)生:
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream;/*** 亂碼的產(chǎn)生* */ public class CharSetDemo2{public static void main(String[] args) throws IOException{File file = new File("d:" + File.separator + "hello.txt");OutputStream out = new FileOutputStream(file);byte[] bytes = "你好".getBytes("ISO8859-1");out.write(bytes);out.close();} }【運(yùn)行結(jié)果】:
?
??
一般情況下產(chǎn)生亂碼,都是由于編碼不一致的問(wèn)題。
?
對(duì)象的序列化
?
對(duì)象序列化就是把一個(gè)對(duì)象變?yōu)槎M(jìn)制數(shù)據(jù)流的一種方法。
?
一個(gè)類要想被序列化,就行必須實(shí)現(xiàn)java.io.Serializable接口。雖然這個(gè)接口中沒(méi)有任何方法,就如同之前的cloneable接口一樣。實(shí)現(xiàn)了這個(gè)接口之后,就表示這個(gè)類具有被序列化的能力。
?
先讓我們實(shí)現(xiàn)一個(gè)具有序列化能力的類吧:
import java.io.*; /*** 實(shí)現(xiàn)具有序列化能力的類* */ public class SerializableDemo implements Serializable{public SerializableDemo(){}public SerializableDemo(String name, int age){this.name=name;this.age=age;}@Overridepublic String toString(){return "姓名:"+name+" 年齡:"+age;}private String name;private int age; }?這個(gè)類就具有實(shí)現(xiàn)序列化能力,
?
在繼續(xù)將序列化之前,先將一下ObjectInputStream和ObjectOutputStream這兩個(gè)類
?
先給一個(gè)ObjectOutputStream的例子吧:
?
import java.io.Serializable; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream;/*** 實(shí)現(xiàn)具有序列化能力的類* */ public class Person implements Serializable{public Person(){}public Person(String name, int age){this.name = name;this.age = age;}@Overridepublic String toString(){return "姓名:" + name + " 年齡:" + age;}private String name;private int age; } /*** 示范ObjectOutputStream* */ public class ObjectOutputStreamDemo{public static void main(String[] args) throws IOException{File file = new File("d:" + File.separator + "hello.txt");ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));oos.writeObject(new Person("rollen", 20));oos.close();} }【運(yùn)行結(jié)果】:
?
當(dāng)我們查看產(chǎn)生的hello.txt的時(shí)候,看到的是亂碼,呵呵。因?yàn)槭嵌M(jìn)制文件。
?
雖然我們不能直接查看里面的內(nèi)容,但是我們可以使用ObjectInputStream類查看:
import java.io.File; import java.io.FileInputStream; import java.io.ObjectInputStream;/*** ObjectInputStream示范* */ public class ObjectInputStreamDemo{public static void main(String[] args) throws Exception{File file = new File("d:" + File.separator + "hello.txt");ObjectInputStream input = new ObjectInputStream(new FileInputStream(file));Object obj = input.readObject();input.close();System.out.println(obj);} }【運(yùn)行結(jié)果】
?
姓名:rollen??年齡:20
?
到底序列化什么內(nèi)容呢?
?
其實(shí)只有屬性會(huì)被序列化。
?
Externalizable接口
?
被Serializable接口聲明的類的對(duì)象的屬性都將被序列化,但是如果想自定義序列化的內(nèi)容的時(shí)候,就需要實(shí)現(xiàn)Externalizable接口。
?
當(dāng)一個(gè)類要使用Externalizable這個(gè)接口的時(shí)候,這個(gè)類中必須要有一個(gè)無(wú)參的構(gòu)造函數(shù),如果沒(méi)有的話,在構(gòu)造的時(shí)候會(huì)產(chǎn)生異常,這是因?yàn)樵诜葱蛄性挼臅r(shí)候會(huì)默認(rèn)調(diào)用無(wú)參的構(gòu)造函數(shù)。
?
現(xiàn)在我們來(lái)演示一下序列化和反序列化:
package IO;import java.io.Externalizable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream;/*** 序列化和反序列化的操作* */ public class ExternalizableDemo{public static void main(String[] args) throws Exception{ser(); // 序列化dser(); // 反序列話 }public static void ser() throws Exception{File file = new File("d:" + File.separator + "hello.txt");ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));out.writeObject(new Person("rollen", 20));out.close();}public static void dser() throws Exception{File file = new File("d:" + File.separator + "hello.txt");ObjectInputStream input = new ObjectInputStream(new FileInputStream(file));Object obj = input.readObject();input.close();System.out.println(obj);} }class Person implements Externalizable{public Person(){}public Person(String name, int age){this.name = name;this.age = age;}@Overridepublic String toString(){return "姓名:" + name + " 年齡:" + age;}// 復(fù)寫(xiě)這個(gè)方法,根據(jù)需要可以保存的屬性或者具體內(nèi)容,在序列化的時(shí)候使用 @Overridepublic void writeExternal(ObjectOutput out) throws IOException{out.writeObject(this.name);out.writeInt(age);}// 復(fù)寫(xiě)這個(gè)方法,根據(jù)需要讀取內(nèi)容 反序列話的時(shí)候需要 @Overridepublic void readExternal(ObjectInput in) throws IOException,ClassNotFoundException{this.name = (String) in.readObject();this.age = in.readInt();}private String name;private int age; }?【運(yùn)行結(jié)果】:
?
姓名:rollen??年齡:20
?
本例中,我們將全部的屬性都保留了下來(lái),
?
Serializable接口實(shí)現(xiàn)的操作其實(shí)是吧一個(gè)對(duì)象中的全部屬性進(jìn)行序列化,當(dāng)然也可以使用我們上使用是Externalizable接口以實(shí)現(xiàn)部分屬性的序列化,但是這樣的操作比較麻煩,
?
當(dāng)我們使用Serializable接口實(shí)現(xiàn)序列化操作的時(shí)候,如果一個(gè)對(duì)象的某一個(gè)屬性不想被序列化保存下來(lái),那么我們可以使用transient關(guān)鍵字進(jìn)行說(shuō)明:
?
下面舉一個(gè)例子:
package IO;import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable;/*** 序列化和反序列化的操作* */ public class serDemo{public static void main(String[] args) throws Exception{ser(); // 序列化dser(); // 反序列話 }public static void ser() throws Exception{File file = new File("d:" + File.separator + "hello.txt");ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));out.writeObject(new Person1("rollen", 20));out.close();}public static void dser() throws Exception{File file = new File("d:" + File.separator + "hello.txt");ObjectInputStream input = new ObjectInputStream(new FileInputStream(file));Object obj = input.readObject();input.close();System.out.println(obj);} }class Person1 implements Serializable{public Person1(){}public Person1(String name, int age){this.name = name;this.age = age;}@Overridepublic String toString(){return "姓名:" + name + " 年齡:" + age;}// 注意這里private transient String name;private int age; }?【運(yùn)行結(jié)果】:
?
姓名:null??年齡:20
?
最后在給一個(gè)序列化一組對(duì)象的例子吧:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable;/*** 序列化一組對(duì)象* */ public class SerDemo1{public static void main(String[] args) throws Exception{Student[] stu = { new Student("hello", 20), new Student("world", 30),new Student("rollen", 40) };ser(stu);Object[] obj = dser();for(int i = 0; i < obj.length; ++i){Student s = (Student) obj[i];System.out.println(s);}}// 序列化public static void ser(Object[] obj) throws Exception{File file = new File("d:" + File.separator + "hello.txt");ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));out.writeObject(obj);out.close();}// 反序列化public static Object[] dser() throws Exception{File file = new File("d:" + File.separator + "hello.txt");ObjectInputStream input = new ObjectInputStream(new FileInputStream(file));Object[] obj = (Object[]) input.readObject();input.close();return obj;} }class Student implements Serializable{public Student(){}public Student(String name, int age){this.name = name;this.age = age;}@Overridepublic String toString(){return "姓名: " + name + " 年齡:" + age;}private String name;private int age; }【運(yùn)行結(jié)果】:
?
姓名:??hello??年齡:20
?
姓名:??world??年齡:30
?
姓名:??rollen??年齡:40
轉(zhuǎn)載于:https://www.cnblogs.com/hujingwei/p/5147435.html
總結(jié)
- 上一篇: Mongo系列之update
- 下一篇: 智芯传感压力传感器在咖啡机中的应用