您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>源碼下載>java源碼下載>

關(guān)于java中的io流知識(shí)總結(jié)詳解

大?。?/span>0.5 MB 人氣: 2017-09-28 需要積分:1

  一、Java io的開(kāi)始:文件

  1. 我們主要講的是流,流的本質(zhì)也是對(duì)文件的處理,我們循序漸進(jìn)一步一步從文件將到流去。

  2. java 處理文件的類(lèi) File,java提供了十分詳細(xì)的文件處理方法,舉了其中幾個(gè)例子,其余的可以去

  packagecom.hxw.io; importjava.io.*; publicclassFileExample{publicstaticvoidmain(String[] args) { createFile(); } /** * 文件處理示例 */publicstaticvoidcreateFile() { File f= newFile( “E:/電腦桌面/jar/files/create.txt”); try{ f.createNewFile(); //當(dāng)且僅當(dāng)不存在具有此抽象路徑名指定名稱(chēng)的文件時(shí),不可分地創(chuàng)建一個(gè)新的空文件。 System.out.println( “該分區(qū)大小”+f.getTotalSpace()/( 1024* 1024* 1024)+ “G”); //返回由此抽象路徑名表示的文件或目錄的名稱(chēng)。 f.mkdirs(); //創(chuàng)建此抽象路徑名指定的目錄,包括所有必需但不存在的父目錄。 // f.delete(); // 刪除此抽象路徑名表示的文件或目錄 System.out.println( “文件名 ”+f.getName()); // 返回由此抽象路徑名表示的文件或目錄的名稱(chēng)。 System.out.println( “文件父目錄字符串 ”+f.getParent()); // 返回此抽象路徑名父目錄的路徑名字符串;如果此路徑名沒(méi)有指定父目錄,則返回 null。 } catch(Exception e) { e.printStackTrace(); } } }

  二、字節(jié)流:

  1.字節(jié)流有輸入和輸出流,我們首先看輸入流InputStream,我們首先解析一個(gè)例子(FileInputStream)。

  packagecom.hxw.io; importjava.io.File; importjava.io.FileInputStream;importjava.io.IOException; importjava.io.InputStream; publicclassFileCount{/** * 我們寫(xiě)一個(gè)檢測(cè)文件長(zhǎng)度的小程序,別看這個(gè)程序挺長(zhǎng)的,你忽略try catch塊后發(fā)現(xiàn)也就那么幾行而已。 */publicstatic voidmain(String[] args) { //TODO 自動(dòng)生成的方法存根 intcount= 0; //統(tǒng)計(jì)文件字節(jié)長(zhǎng)度 InputStreamstreamReader = null; //文件輸入流 try{ streamReader=newFileInputStream( newFile( “D:/David/Java/java 高級(jí)進(jìn)階/files/tiger.jpg”)); /*1.new File()里面的文件地址也可以寫(xiě)成D:\\David\\Java\\java 高級(jí)進(jìn)階\\files\\tiger.jpg,前一個(gè)\是用來(lái)對(duì)后一個(gè) * 進(jìn)行轉(zhuǎn)換的,F(xiàn)ileInputStream是有緩沖區(qū)的,所以用完之后必須關(guān)閉,否則可能導(dǎo)致內(nèi)存占滿,數(shù)據(jù)丟失。 */while(streamReader.read()!=- 1) { //讀取文件字節(jié),并遞增指針到下一個(gè)字節(jié) count++; } System.out.println( “---長(zhǎng)度是: ”+count+ “ 字節(jié)”); } catch( finalIOException e) { //TODO 自動(dòng)生成的 catch 塊 e.printStackTrace(); } finally{ try{ streamReader.close(); }catch(IOException e) { //TODO 自動(dòng)生成的 catch 塊 e.printStackTrace(); } } } }

  我們一步一步來(lái),首先,上面的程序存在問(wèn)題是,每讀取一個(gè)自己我都要去用到FileInputStream,我輸出的結(jié)果是“—長(zhǎng)度是: 64982 字節(jié)”,那么進(jìn)行了64982次操作!可能想象如果文件十分龐大,這樣的操作肯定會(huì)出大問(wèn)題,所以引出了緩沖區(qū)的概念??梢詫treamReader.read()改成streamReader.read(byte[]b)此方法讀取的字節(jié)數(shù)目等于字節(jié)數(shù)組的長(zhǎng)度,讀取的數(shù)據(jù)被存儲(chǔ)在字節(jié)數(shù)組中,返回讀取的字節(jié)數(shù),InputStream還有其他方法mark,reset,markSupported方法,例如:

  markSupported 判斷該輸入流能支持mark 和 reset 方法。

  mark用于標(biāo)記當(dāng)前位置;在讀取一定數(shù)量的數(shù)據(jù)(小于readlimit的數(shù)據(jù))后使用reset可以回到mark標(biāo)記的位置。

  FileInputStream不支持mark/reset操作;BufferedInputStream支持此操作;

  mark(readlimit)的含義是在當(dāng)前位置作一個(gè)標(biāo)記,制定可以重新讀取的最大字節(jié)數(shù),也就是說(shuō)你如果標(biāo)記后讀取的字節(jié)數(shù)大于readlimit,你就再也回不到回來(lái)的位置了。

  通常InputStream的read()返回-1后,說(shuō)明到達(dá)文件尾,不能再讀取。除非使用了mark/reset。

  2.FileOutputStream 循序漸進(jìn)版, InputStream是所有字節(jié)輸出流的父類(lèi),子類(lèi)有ByteArrayOutputStream,F(xiàn)ileOutputStream,ObjectOutputStreanm,這些我們?cè)诤竺娑紩?huì)一一說(shuō)到。先說(shuō)FileOutputStream

  我以一個(gè)文件復(fù)制程序來(lái)說(shuō),順便演示一下緩存區(qū)的使用。(Java I/O默認(rèn)是不緩沖流的,所謂“緩沖”就是先把從流中得到的一塊字節(jié)序列暫存在一個(gè)被稱(chēng)為buffer的內(nèi)部字節(jié)數(shù)組里,然后你可以一下子取到這一整塊的字節(jié)數(shù)據(jù),沒(méi)有緩沖的流只能一個(gè)字節(jié)一個(gè)字節(jié)讀,效率孰高孰低一目了然。有兩個(gè)特殊的輸入流實(shí)現(xiàn)了緩沖功能,一個(gè)是我們常用的BufferedInputStream.)

  packagecom.hxw.io; importjava.io.*; /** * Java學(xué)習(xí)交流QQ群:589809992 我們一起學(xué)Java! */publicclassFileCopy{publicstaticvoidmain(String[] args) { // TODO自動(dòng)生成的方法存根 byte[] buffer= newbyte[ 512]; //一次取出的字節(jié)數(shù)大小,緩沖區(qū)大小 intnumberRead= 0; FileInputStream input= null; FileOutputStream out = null; try{ input= newFileInputStream(“D:/David/Java/java 高級(jí)進(jìn)階/files/tiger.jpg”); out= newFileOutputStream(“D:/David/Java/java 高級(jí)進(jìn)階/files/tiger2.jpg”); //如果文件不存在會(huì)自動(dòng)創(chuàng)建while((numberRead=input.read(buffer))!=- 1) { //numberRead的目的在于防止最后一次讀取的字節(jié)小于buffer長(zhǎng)度, out.write(buffer, 0, numberRead); //否則會(huì)自動(dòng)被填充0 } } catch(finalIOException e) { // TODO自動(dòng)生成的 catch 塊 e.printStackTrace(); } finally{ try{ input.close(); out.close(); } catch(IOException e) { // TODO自動(dòng)生成的 catch 塊e.printStackTrace(); } } } }

  3.讀寫(xiě)對(duì)象:ObjectInputStream 和ObjectOutputStream ,該流允許讀取或?qū)懭胗脩糇远x的類(lèi),但是要實(shí)現(xiàn)這種功能,被讀取和寫(xiě)入的類(lèi)必須實(shí)現(xiàn)Serializable接口,其實(shí)該接口并沒(méi)有什么方法,可能相當(dāng)于一個(gè)標(biāo)記而已,但是確實(shí)不合缺少的。實(shí)例代碼如下:

  packagecom.hxw.io; importjava.io.*; publicclassObjetStream{/** *@paramargs */publicstaticvoidmain(String[] args) { // TODO自動(dòng)生成的方法存根 ObjectOutputStream objectwriter= null; ObjectInputStream objectreader= null; try{ objectwriter=newObjectOutputStream( newFileOutputStream( “D:/David/Java/java 高級(jí)進(jìn)階/files/student.txt”)); objectwriter.writeObject( newStudent( “gg”, 22)); objectwriter.writeObject( newStudent( “tt”, 18)); objectwriter.writeObject( newStudent( “rr”,17)); objectreader= newObjectInputStream( newFileInputStream( “D:/David/Java/java 高級(jí)進(jìn)階/files/student.txt”)); for( inti = 0; i 《 3; i++) { System.out.println(objectreader.readObject()); } } catch(IOException | ClassNotFoundException e) { // TODO自動(dòng)生成的 catch 塊 e.printStackTrace(); } finally{try{ objectreader.close(); objectwriter.close(); } catch(IOException e) { // TODO自動(dòng)生成的 catch 塊 e.printStackTrace(); } } } } class Student implements Serializable{ privateString name; privateintage; publicStudent(String name, intage) { super(); this.name = name;this.age = age; } @OverridepublicString toString() { return“Student [name=”+ name + “, age=”+ age + “]”; } }

  運(yùn)行后系統(tǒng)輸出:

  Student [name=gg, age=22]

  Student [name=tt, age=18]

  Student [name=rr, age=17]

  4.有時(shí)沒(méi)有必要存儲(chǔ)整個(gè)對(duì)象的信息,而只是要存儲(chǔ)一個(gè)對(duì)象的成員數(shù)據(jù),成員數(shù)據(jù)的類(lèi)型假設(shè)都是Java的基本數(shù)據(jù)類(lèi)型,這樣的需求不必使用到與Object輸入、輸出相關(guān)的流對(duì)象,可以使用DataInputStream、DataOutputStream來(lái)寫(xiě)入或讀出數(shù)據(jù)。下面是一個(gè)例子:(DataInputStream的好處在于在從文件讀出數(shù)據(jù)時(shí),不用費(fèi)心地自行判斷讀入字符串時(shí)或讀入int類(lèi)型時(shí)何時(shí)將停止,使用對(duì)應(yīng)的readUTF()和readInt()方法就可以正確地讀入完整的類(lèi)型數(shù)據(jù)。)

  packagecom.hxw; /** * Java學(xué)習(xí)交流QQ群:589809992 我們一起學(xué)Java! */publicclassMember{privateString name; privateintage; publicMember() { }publicMember(String name, intage) { this.name = name; this.age = age; }publicvoidsetName(String name){ this.name = name; } publicvoidsetAge( intage) { this.age = age; } publicString getName() { returnname; } publicintgetAge() { returnage; } }

  打算將Member類(lèi)實(shí)例的成員數(shù)據(jù)寫(xiě)入文件中,并打算在讀入文件數(shù)據(jù)后,將這些數(shù)據(jù)還原為Member對(duì)象。下面的代碼簡(jiǎn)單示范了如何實(shí)現(xiàn)這個(gè)需求。

  packagecom.hxw; importjava.io.*; /** * Java學(xué)習(xí)交流QQ群:589809992 我們一起學(xué)Java! */publicclassDataStreamDemo{publicstaticvoidmain(String[]args) { Member[] members = {newMember( “Justin”, 90), newMember( “momor”, 95), newMember( “Bush”,88)}; try{ DataOutputStreamdataOutputStream = newDataOutputStream(newFileOutputStream(args[ 0])); for(Member member:members) { //寫(xiě)入U(xiǎn)TF字符串dataOutputStream.writeUTF(member.getName()); //寫(xiě)入int數(shù)據(jù)dataOutputStream.writeInt(member.getAge()); } //所有數(shù)據(jù)至目的地dataOutputStream.flush(); //關(guān)閉流 dataOutputStream.close(); DataInputStreamdataInputStream = newDataInputStream( newFileInputStream(args[ 0]));//讀出數(shù)據(jù)并還原為對(duì)象 for(inti= 0;i《members.length;i++) { //讀出UTF字符串 String name =dataInputStream.readUTF(); //讀出int數(shù)據(jù) intscore =dataInputStream.readInt(); members[i] = newMember(name,score); } //關(guān)閉流 dataInputStream.close(); //顯示還原后的數(shù)據(jù) for(Member member : members) { System.out.printf(“%s\t%d%n”,member.getName(),member.getAge()); } } catch(IOException e) { e.printStackTrace(); } } }

  5.PushbackInputStream類(lèi)繼承了FilterInputStream類(lèi)是iputStream類(lèi)的修飾者。提供可以將數(shù)據(jù)插入到輸入流前端的能力(當(dāng)然也可以做其他操作)。簡(jiǎn)而言之PushbackInputStream類(lèi)的作用就是能夠在讀取緩沖區(qū)的時(shí)候提前知道下一個(gè)字節(jié)是什么,其實(shí)質(zhì)是讀取到下一個(gè)字符后回退的做法,這之間可以進(jìn)行很多操作,這有點(diǎn)向你把讀取緩沖區(qū)的過(guò)程當(dāng)成一個(gè)數(shù)組的遍歷,遍歷到某個(gè)字符的時(shí)候可以進(jìn)行的操作,當(dāng)然,如果要插入,能夠插入的最大字節(jié)數(shù)是與推回緩沖區(qū)的大小相關(guān)的,插入字符肯定不能大于緩沖區(qū)吧!下面是一個(gè)示例。

  packagecom.hxw.io; importjava.io.ByteArrayInputStream; //導(dǎo)入ByteArrayInputStream的包 importjava.io.IOException; importjava.io.PushbackInputStream; /** * 回退流操作 * */publicclassPushBackInputStreamDemo{publicstaticvoidmain(String[] args)throwsIOException { String str = “hello,rollenholt”; PushbackInputStream push = null; // 聲明回退流對(duì)象 ByteArrayInputStream bat = null; // 聲明字節(jié)數(shù)組流對(duì)象 bat =newByteArrayInputStream(str.getBytes()); push = newPushbackInputStream(bat); // 創(chuàng)建回退流對(duì)象,將拆解的字節(jié)數(shù)組流傳入 inttemp = 0; while((temp = push.read()) != - 1) { // push.read()逐字節(jié)讀取存放在temp中,如果讀取完成返回-1 if(temp == ‘,’) { // 判斷讀取的是否是逗號(hào) push.unread(temp); //回到temp的位置 temp = push.read(); //接著讀取字節(jié)System.out.print( “(回退”+ ( char) temp + “) ”); // 輸出回退的字符 } else{ System.out.print((char) temp); // 否則輸出字符 } } } }

  6.SequenceInputStream:有些情況下,當(dāng)我們需要從多個(gè)輸入流中向程序讀入數(shù)據(jù)。此時(shí),可以使用合并流,將多個(gè)輸入流合并成一個(gè)SequenceInputStream流對(duì)象。SequenceInputStream會(huì)將與之相連接的流集組合成一個(gè)輸入流并從第一個(gè)輸入流開(kāi)始讀取,直到到達(dá)文件末尾,接著從第二個(gè)輸入流讀取,依次類(lèi)推,直到到達(dá)包含的最后一個(gè)輸入流的文件末尾為止。 合并流的作用是將多個(gè)源合并合一個(gè)源。其可接收枚舉類(lèi)所封閉的多個(gè)字節(jié)流對(duì)象。

  packagecom.hxw.io; importjava.io.*; importjava.util.Enumeration; importjava.util.Vector;publicclassSequenceInputStreamTest{/** *@paramargs * SequenceInputStream合并流,將與之相連接的流集組合成一個(gè)輸入流并從第一個(gè)輸入流開(kāi)始讀取, * 直到到達(dá)文件末尾,接著從第二個(gè)輸入流讀取,依次類(lèi)推,直到到達(dá)包含的最后一個(gè)輸入流的文件末尾為止。 * 合并流的作用是將多個(gè)源合并合一個(gè)源。可接收枚舉類(lèi)所封閉的多個(gè)字節(jié)流對(duì)象。 */publicstaticvoidmain(String[] args) { doSequence(); } privatestaticvoiddoSequence() { // 創(chuàng)建一個(gè)合并流的對(duì)象 SequenceInputStream sis = null; // 創(chuàng)建輸出流。BufferedOutputStream bos = null; try{ // 構(gòu)建流集合。 Vector《InputStream》 vector =newVector《InputStream》(); vector.addElement( newFileInputStream( “D:\text1.txt”)); vector.addElement( newFileInputStream( “D:\text2.txt”)); vector.addElement(newFileInputStream( “D:\text3.txt”)); Enumeration《InputStream》 e = vector.elements(); sis = newSequenceInputStream(e); bos = newBufferedOutputStream( newFileOutputStream(“D:\text4.txt”)); // 讀寫(xiě)數(shù)據(jù) byte[] buf = newbyte[ 1024]; intlen = 0; while((len = sis.read(buf)) != - 1) { bos.write(buf, 0, len); bos.flush(); } } catch(FileNotFoundException e1) { e1.printStackTrace(); } catch(IOException e1) { e1.printStackTrace(); } finally{ try{if(sis != null) sis.close(); } catch(IOException e) { e.printStackTrace(); } try{ if(bos != null) bos.close(); } catch(IOException e) { e.printStackTrace(); } } } }

  7.PrintStream 說(shuō)這個(gè)名字可能初學(xué)者不熟悉,如果說(shuō)System.out.print()你肯定熟悉,System.out這個(gè)對(duì)象就是PrintStream,這個(gè)我們不做過(guò)多示例

  三、字符流(顧名思義,就是操作字符文件的流)

  1.java 使用Unicode存儲(chǔ)字符串,在寫(xiě)入字符流時(shí)我們都可以指定寫(xiě)入的字符串的編碼。前面介紹了不用拋異常的處理字節(jié)型數(shù)據(jù)的流ByteArrayOutputStream,與之對(duì)應(yīng)的操作字符類(lèi)的類(lèi)就是CharArrayReader,CharArrayWriter類(lèi),這里也會(huì)用到緩沖區(qū),不過(guò)是字符緩沖區(qū),一般講字符串放入到操作字符的io流一般方法是

  CharArrayReaderreader=mew CharArrayReader(str.toCharArray()); 一旦會(huì)去到CharArrayReader實(shí)例就可以使用CharArrayReader訪問(wèn)字符串的各個(gè)元素以執(zhí)行進(jìn)一步讀取操作。不做例子

  2.我們用FileReader ,PrintWriter來(lái)做示范

  packagecom.hxw.io; importjava.io.FileNotFoundException; importjava.io.FileReader;importjava.io.IOException; importjava.io.PrintWriter; importjava.nio.CharBuffer;publicclassPrint{/** *@paramargs */publicstaticvoidmain(String[] args) { // TODO自動(dòng)生成的方法存根 char[] buffer= newchar[ 512]; //一次取出的字節(jié)數(shù)大小,緩沖區(qū)大小intnumberRead= 0; FileReader reader= null; //讀取字符文件的流 PrintWriter writer= null; //寫(xiě)字符到控制臺(tái)的流 try{ reader= newFileReader( “D:/David/Java/java 高級(jí)進(jìn)階/files/copy1.txt”); writer= newPrintWriter(System.out); //PrintWriter可以輸出字符到文件,也可以輸出到控制臺(tái) while((numberRead=reader.read(buffer))!=- 1) { writer.write(buffer, 0, numberRead); } } catch(IOException e) { // TODO自動(dòng)生成的 catch 塊 e.printStackTrace(); } finally{ try{ reader.close(); } catch(IOException e) { // TODO自動(dòng)生成的 catch 塊e.printStackTrace(); } writer.close(); //這個(gè)不用拋異常 } } }

  3.相對(duì)我們前面的例子是直接用FileReader打開(kāi)的文件,我們這次使用鏈接流,一般比較常用的都用鏈接流,所謂鏈接流就是就多次對(duì)流的封裝,這樣能更好的操作個(gè)管理數(shù)據(jù),(比如我們利用DataInputStream(BufferedInputStream(FileInputStream))將字節(jié)流層層包裝后,我們可以讀取readByte(),readChar()這樣更加具體的操作,注意,該流屬于字節(jié)流對(duì)字符進(jìn)行操作,)字符流用CharArrayReader就可以了。下面的示例我們將用到j(luò)2se 5中的一個(gè)可變參數(shù)進(jìn)行一個(gè)小度擴(kuò)展。使用BufferedWriter 和BufferedReader用文件級(jí)聯(lián)的方式進(jìn)行寫(xiě)入,即將多個(gè)文件寫(xiě)入到同一文件中(自帶緩沖區(qū)的輸出輸出流BufferedReader和BufferedWriter,該流最常用的屬readLine()方法了,讀取一行數(shù)據(jù),并返回String)。

  packagecom.hxw.io; importjava.io.BufferedReader; importjava.io.BufferedWriter;importjava.io.FileReader; importjava.io.FileWriter; importjava.io.IOException;importjava.util.Iterator; publicclassFileConcatenate{/** * 包裝類(lèi)進(jìn)行文件級(jí)聯(lián)操作 */publicstaticvoidmain(String[] args) { // TODO自動(dòng)生成的方法存根 try{ concennateFile(args); } catch(IOException e) { // TODO自動(dòng)生成的 catch 塊e.printStackTrace(); } } publicstaticvoidconcennateFile(String.。.fileName)throwsIOException{ String str; //構(gòu)建對(duì)該文件您的輸入流 BufferedWriter writer=newBufferedWriter( newFileWriter( “D:/David/Java/java 高級(jí)進(jìn)階/files/copy2.txt”));for(String name: fileName){ BufferedReader reader= newBufferedReader(newFileReader(name)); while((str=reader.readLine())!= null) { writer.write(str); writer.newLine(); } } } }

  4.Console類(lèi),該類(lèi)提供了用于讀取密碼的方法,可以禁止控制臺(tái)回顯并返回char數(shù)組,對(duì)兩個(gè)特性對(duì)保證安全有作用,平時(shí)用的不多,了解就行。

  5.StreamTokenizer 類(lèi),這個(gè)類(lèi)非常有用,它可以把輸入流解析為標(biāo)記(token), StreamTokenizer 并非派生自InputStream或者OutputStream,而是歸類(lèi)于io庫(kù)中,因?yàn)镾treamTokenizer只處理InputStream對(duì)象。

  首先給出我的文本文件內(nèi)容:

  ‘水上漂’

  青青草

  “i love wyhss”

  {3211}

  23223 3523

  i love wyh ,。

  。 ,

  下面是代碼:

  packagecom.hxw.io; importjava.io.BufferedReader; importjava.io.FileReader;importjava.io.IOException; importjava.io.StreamTokenizer; /** * 使用StreamTokenizer來(lái)統(tǒng)計(jì)文件中的字符數(shù) * StreamTokenizer 類(lèi)獲取輸入流并將其分析為“標(biāo)記”,允許一次讀取一個(gè)標(biāo)記。 * 分析過(guò)程由一個(gè)表和許多可以設(shè)置為各種狀態(tài)的標(biāo)志控制。 * 該流的標(biāo)記生成器可以識(shí)別標(biāo)識(shí)符、數(shù)字、引用的字符串和各種注釋樣式。 * * 默認(rèn)情況下,StreamTokenizer認(rèn)為下列內(nèi)容是Token: 字母、數(shù)字、除C和C++注釋符號(hào)以外的其他符號(hào)。 * 如符號(hào)“/”不是Token,注釋后的內(nèi)容也不是,而“\”是Token。單引號(hào)和雙引號(hào)以及其中的內(nèi)容,只能算是一個(gè)Token。 * 統(tǒng)計(jì)文章字符數(shù)的程序,不是簡(jiǎn)單的統(tǒng)計(jì)Token數(shù)就萬(wàn)事大吉,因?yàn)樽址麛?shù)不等于Token。按照Token的規(guī)定, * 引號(hào)中的內(nèi)容就算是10頁(yè)也算一個(gè)Token。如果希望引號(hào)和引號(hào)中的內(nèi)容都算作Token,應(yīng)該調(diào)用下面的代碼: * st.ordinaryChar(‘\’‘); * st.ordinaryChar(’\“‘); */publicclassStreamTokenizerExample{/** * 統(tǒng)計(jì)字符數(shù) *@paramfileName 文件名 *@return字符數(shù) */publicstaticvoidmain(String[] args) { String fileName = ”D:/David/Java/java 高級(jí)進(jìn)階/files/copy1.txt“; StreamTokenizerExample.statis(fileName); } publicstaticlongstatis(String fileName) { FileReader fileReader = null; try{ fileReader = newFileReader(fileName); //創(chuàng)建分析給定字符流的標(biāo)記生成器 StreamTokenizer st = newStreamTokenizer( newBufferedReader( fileReader)); //ordinaryChar方法指定字符參數(shù)在此標(biāo)記生成器中是“普通”字符。 //下面指定單引號(hào)、雙引號(hào)和注釋符號(hào)是普通字符 st.ordinaryChar( ’\‘’); st.ordinaryChar( ‘\”’); st.ordinaryChar( ‘/’); String s; intnumberSum = 0; intwordSum = 0; intsymbolSum = 0;inttotal = 0; //nextToken方法讀取下一個(gè)Token. //TT_EOF指示已讀到流末尾的常量。while(st.nextToken() !=StreamTokenizer.TT_EOF) { //在調(diào)用 nextToken 方法之后,ttype字段將包含剛讀取的標(biāo)記的類(lèi)型 switch(st.ttype) { //TT_EOL指示已讀到行末尾的常量。caseStreamTokenizer.TT_EOL: break; //TT_NUMBER指示已讀到一個(gè)數(shù)字標(biāo)記的常量caseStreamTokenizer.TT_NUMBER: //如果當(dāng)前標(biāo)記是一個(gè)數(shù)字,nval字段將包含該數(shù)字的值 s = String.valueOf((st.nval)); System.out.println( “數(shù)字有:”+s); numberSum ++;break; //TT_WORD指示已讀到一個(gè)文字標(biāo)記的常量 caseStreamTokenizer.TT_WORD: //如果當(dāng)前標(biāo)記是一個(gè)文字標(biāo)記,sval字段包含一個(gè)給出該文字標(biāo)記的字符的字符串 s = st.sval; System.out.println( “單詞有: ”+s); wordSum ++; break; default: //如果以上3中類(lèi)型都不是,則為英文的標(biāo)點(diǎn)符號(hào) s = String.valueOf(( char) st.ttype); System.out.println( “標(biāo)點(diǎn)有: ”+s); symbolSum ++; } } System.out.println( “數(shù)字有 ”+ numberSum+ “個(gè)”); System.out.println( “單詞有 ”+ wordSum+ “個(gè)”); System.out.println( “標(biāo)點(diǎn)符號(hào)有: ”+ symbolSum+ “個(gè)”); total = symbolSum + numberSum +wordSum; System.out.println(“Total = ”+ total); returntotal; } catch(Exception e) { e.printStackTrace(); return- 1; } finally{if(fileReader != null) { try{ fileReader.close(); } catch(IOException e1) { } } } } }

  運(yùn)行結(jié)果為:

  標(biāo)點(diǎn)有: ’

  單詞有: 水上漂

  標(biāo)點(diǎn)有: ’

  單詞有: 青青草

  標(biāo)點(diǎn)有: ”

  單詞有: i

  單詞有: love

  單詞有: wyh

  單詞有: ss

  標(biāo)點(diǎn)有: ”

  標(biāo)點(diǎn)有: {

  數(shù)字有:3211.0

  標(biāo)點(diǎn)有: }

  數(shù)字有:23223.0

  數(shù)字有:35.23

  單詞有: i

  單詞有: love

  單詞有: wyh

  單詞有: ,。

  數(shù)字有:0.0

  標(biāo)點(diǎn)有: ,

  數(shù)字有 4個(gè)

  單詞有 10個(gè)

  標(biāo)點(diǎn)符號(hào)有: 7個(gè)

  Total= 21

  我們從其中可以看到很多東西:

  1.一個(gè)單獨(dú)的小數(shù)點(diǎn)“。”是被當(dāng)做一個(gè)數(shù)字來(lái)對(duì)待的,數(shù)字的值為0.0;

  2.一串漢字只要中間沒(méi)有符號(hào)(空格回車(chē) 分號(hào)等等)都是被當(dāng)做一個(gè)單詞的。中文的標(biāo)點(diǎn)跟中文的漢字一樣處理

  3.如果不對(duì)引號(hào)化成普通字符,一個(gè)引號(hào)內(nèi)的內(nèi)容不論多少都被當(dāng)做是一個(gè)標(biāo)記。

  4.該類(lèi)能夠識(shí)別英文標(biāo)點(diǎn)

  5.java io里面還有其他接口類(lèi)似Serializable接口的子接口Externalizable接口,比Serializable復(fù)雜一些,這里不再介紹。還有關(guān)于java對(duì)象版本化的東西感興趣的可以百度。java nio的東西這里沒(méi)有涉及,后續(xù)會(huì)結(jié)合到線程再發(fā)一篇文章專(zhuān)門(mén)解析這個(gè)東西。

非常好我支持^.^

(0) 0%

不好我反對(duì)

(0) 0%

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?