??? File類
?一個File類的對象,表示了磁盤上的文件或目錄。
?File類提供了與平臺無關的方法來對磁盤上的文件或目錄進行操作。
import java.io.*;
class FileTest
{
?public static void main(String[] args) throws Exception
?{
? //File f = new File("1.txt");
? //f.createNewFile();?? 創建文件
? //f.mkdir(); 創建文件夾
? //File f = new File("F:\\Java Develop\\1.txt");//使用絕對路徑
? //f.createNewFile();
? /*
? *WINDOWS平臺下有盤符,LINUX下是沒有的
? *考慮到JAVA語言的平臺性,所有用分隔符seperator/seperatorChar
? */
? /*
? File fDir = new File(File.separator);//創建了當前的根目錄
? String strFile = "Java Develop"+File.separator+"1.txt";
? File f = new File(fDir,strFile);
? f.createNewFile();
? //f.delete();
? f.deleteOnExit();
? Thread.sleep(3000);
? */
? /*
? for(int i=0;i<5;i++)
? {
?? File.createTempFile("linshi",".tmp");
?? f.deleteOnExit();
? }
? Thread.sleep(3000);
? */
?
? File fDir = new File(File.separator);
? String strFile ="Java Develop"+File.separator;
? File f = new File(fDir,strFile);
? //文件過濾器
? String[] names = f.list(new FilenameFilter()
? {
?? public boolean accept(File dir,String name)
?? {
??? return name.indexOf(".java")!=-1;
?? }
? });
? for(int i=0;i<names.length;i++)
? {
?? System.out.println(names[i]);
? }
?}
}
??????????? 流式I/0
?流(Stream)是字節的源或目的。
?兩種基本的流是: 輸入流(Input Stream)和輸出流(Output Stream)。從從中讀出一系列字節的
?對象稱為輸入流。而能向其中寫入一系列字節的對象稱為輸出流。
?????????? 流的分類
?
?節點流: 從特定的地方讀寫的流類,例如:磁盤或一塊內存區域。
?過濾流: 使用節點作為輸入或輸出。過濾流使用的是一個已經存在的輸入流或輸出流連接創建的。
?(如下圖)
?InputStream(一個抽象的基類)
?.三個基本的讀寫方法
? abstract int read(): 讀取一個字節數據,并返回到數據,如果返回-1,表示讀到了輸入流的
?????????????????????? 末尾。
? int read(byte[] b):? 將數據讀入一個字節數組,同時返回實際讀取的字節數。如果返回-1,
?????????????????????? 表示讀到了輸入流的末尾。
? int read(byte[] b,int off,int len): 將數據讀入一個字節數組,同時返回是實際讀取的字
?????????????????????? 節數。如果返回-1,表示讀到了輸入流的末尾。off指定在數組b中存放
?????????????????????? 數據的起始偏移位置;len指定讀取的最大字節數。
?其他的方法
? long-skip(long n): 在輸入流中跳過n個字節,并返回實際跳過的字節數。
? int available():?? 返回在不發生阻塞的情況下,可讀取的字節數。
? void close():????? 關閉輸入流,釋放和這個流相關的系統資源。
? void mark(int reqdlimit): 在輸入流的當前位置放置一個標記,如果讀取的字節數多余
???????????????????? readlimit設置的值,則流忽略這個標記。
? void reset():????? 返回到上一個標記。
? boolean markSupported(): 測試當前是否支持mark和reset方法。如果支持返回true,反之false。
???????? java.io包中的InputStream的類層次 (下圖)
OutputStream
?三個基本的寫方法
?abstract void write(int b): 往輸出流中寫入一個字節
?void write(byte[] b):?????? 往輸出流中寫入數組b中的所有字節
?void writte(byte[] b,int off,int len): 往輸出流中寫入數組b中從偏移量off開始的len個
???????????????????????????? 字節的數據
?其它方法
?void flush(): 刷新輸出流,強制緩沖區中的輸出字節被寫出
?void close(): 關閉輸出流,釋放和這個流相關的系統資源
??????? java.io包中OutputStream的類層次(如下圖)
基本的流類
?FileInputStream和FileOutputStream
?節點流,用于從文件中讀取或往文件中寫入字節流。如果在構造FileOutputStream時,文件已經
?存在,則覆蓋這個文件。
?
?BufferedInputStream和BufferedOutputStream
?過濾流,需要使用已經存在的節點流來構造,提供帶緩沖的讀寫,提高了讀寫的效率。
?DataInputStream和DataOutputStream
?過濾流,需要使用已經存在的節點流來構造,提供了讀寫Java中的基本數據類型的功能。
?PipedInputStream和PipedOutputStream
?管道流,用于線程間的通信。一個線程的PipedInputStream對象從另一個線程的PipedOutputStream
?對象讀取輸入。要使管道流有用,必須同時構造管道輸入流和管道輸出流。
code:
import java.io.*;
class StreamTest
{
?public static void main(String[] args)throws Exception
?{
? /*
? int data;
? while((data=System.in.read())!=-1)? //從標準設備讀取數據
? {
?? System.out.write(data);//從標準設備輸出數據
? }
? */
? //輸出流寫數據,只需要關閉尾端的流就可以了,因為fos連接到了bos
? FileOutputStream fos = new FileOutputStream("1.txt");
? //fos.write("());
? //fos.close();
? BufferedOutputStream bos = new BufferedOutputStream(fos);
? //bos.write("http//www.baidu.com".getBytes());
? //bos.flush();
? //bos.close();
? DataOutputStream dos=new DataOutputStream(bos); //連接到了bos和fis
? byte b=3;
? int i=78;
? char ch='a';
? float f=4.5f;
? dos.writeByte(b);
? dos.writeInt(i);
? dos.writeChar(ch);
? dos.writeFloat(f);
? dos.close(); //必須調用flush()或者close()不然不會寫入硬盤
?
? //輸入流讀數據
? FileInputStream fis=new FileInputStream("1.txt");
? BufferedInputStream bis = new BufferedInputStream(fis);
? //byte[] buf=new byte[100];
? //int len=fis.read(buf);
? //int len=bis.read(buf);
? //System.out.println(new String(buf,0,len));
? //fis.close();
? //bis.close();
? //注意讀取的順序要和寫的順序一樣
? DataInputStream dis = new DataInputStream(bis);
? System.out.println(dis.readByte());
? System.out.println(dis.readInt());
? System.out.println(dis.readChar());
? System.out.println(dis.readFloat());
? dis.close();?
?
?}
}
管道輸入/輸出流 code:
import java.io.*;
class PipedStreamTest
{
?public static void main(String[] args)
?{
? PipedOutputStream pos=new PipedOutputStream();
? PipedInputStream pis=new PipedInputStream();
? //連接
? try
? {
?? pos.connect(pis);
?? new Producer(pos).start();
?? new Consumer(pis).start();
? }
? catch(Exception e)
? {
?? e.printStackTrace();
? }
?}
}
class Producer extends Thread
{
?private PipedOutputStream pos;
?public Producer(PipedOutputStream pos)
?{
? this.pos=pos;
?}
?public void run()
?{
? try
? {
?? pos.write("hello,welcome!".getBytes());
?? pos.close();
? }
? catch(Exception e)
? {
?? e.printStackTrace();
? }
?}
}
class Consumer extends Thread
{
?private PipedInputStream pis;
?Consumer(PipedInputStream pis)
?{
? this.pis=pis;
?}
?public void run()
?{
? try
? {
?? byte[] buf=new byte[100];
?? int len=pis.read(buf);
?? System.out.println(new String(buf,0,len));
?? pis.close();
? }
? catch(Exception e)
? {
?? e.printStackTrace();
? }
?}
}
=================================================================================
????????????? Java I/O庫的設計原則
?Java的I/O庫提供了一個稱做鏈接的機制,可以將一個流與另一個流首尾相接,形成一個流管道的鏈接。
?這種機制實際上是一種被稱做為Decorator(裝飾)的設計模式的應用。
?
?通過流的鏈接,可以動態的增加流的功能,而這些功能的增加是通過組合一些流的基本功能而動
?態獲取的。
?我們要獲取一個I/O對象,往往需要產生多個I/O對象,這也是Java I/O庫不大容易掌握的原因,
?但在I/O庫中的Decorator模式的運用,給我們提供了實現上的靈活性。
?I/O流的鏈接圖(如下)
? Reader和Writer
?Java程序語言使用Unicode來表示字符串和字符。
?Reader和Writer這兩個抽象類主要用來讀寫字符流。
?java.io包中Reader的類層次(如下圖)
?java.io包中Writer的類層次(如下圖)
?code:
import java.io.*;
class StreamTest
{
?public static void main(String[] args)throws Exception
?{
? /*
? FileOutputStream fos = new FileOutputStream("1.txt");
? OutputStreamWriter osw = new OutputStreamWriter(fos);
? BufferedWriter bw = new BufferedWriter(osw);
?
? bw.write("? bw.close();
?
? FileInputStream fis = new FileInputStream("1.txt");
? InputStreamReader isr = new InputStreamReader(fis);
? BufferedReader br = new BufferedReader(isr);
? System.out.println(br.readLine());
? br.close();
? */
? //InputStreamReader/OutputStreamWriter是一個中間過度類,連接字符和字符串
? InputStreamReader isr = new InputStreamReader(System.in);
? BufferedReader br = new BufferedReader(isr);
? String strLine;
? while((strLine=br.readLine())!=null)
? {
?? System.out.println(strLine);
? }
? br.close();
?}
}
??????????? 字符集的編碼
?ASCII(American Standard Code for Information Interchange,美國信息互換標準代碼),是基
?于常用的英文字符的一套電腦編碼系統。我們知道英文中經常使用的字符,數字符號被計算機
?處理時都是以二進制編碼的形式出現(bit)二進制數對應。其最高位是0,相應的十進制數是0-127
?如,數字1,有一些制表符和其他符號組成。ASCII是現金最通用的單字節編碼系統。
?GB2312: GB2312碼是中華人民共和國國家漢字信息交換用編碼,全稱《信息交換用漢字編碼字
?符集-基本集》。主要用于給每一個中文字符指定相應的數字,也就是進行編碼。一個中文字符
?用兩個字節的數字來表示,為了和ASCII碼有所區別,將中文字符每一個字節的最高位置都用1
?來表示。
?GBK:為了對更多的字符進行編碼,國家又發布了新的編碼系統GBK(GBK的K是“擴展”的漢語
?拼音的第一個字母)。在新的編碼系統里,除了完全兼容GB2312外,還對繁體中文,一些不常用
?的漢字和許多符號進行了編碼。
?ISO-8859-1:是西方國家所使用的字符編碼集,是一種單字節的字符集,而英文實際上只用了其
?中數字小于128的部分。
?Unicode: 這是一種通用的字符集,對所有語言的文字進行統一編碼,對每一個字符都采用2個字節
?來表示,對于英文字符采取前面加“0”字節的策略實現等長兼容。如"a"的ASCII碼為0x61,
?UNICODE就為0x00,0x61。
?UTF-8: Elight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,
?UCS是所有其他字符集標準的一個超集)。一個7位的ASCII碼值,對應的UTF碼是一個字節,如果
?字符是0x0000,或在0x0080與0x007f之間,對應的UTF碼是兩個字節,如果字符在0x0800與0xffff
?之間,對應的UTF碼是三個字節。
?編碼:將一個Unicode碼轉換為本地字符表示的過程為編碼。
? 解碼:將一個字節轉換為一個字符(用Unicode表示),這個過程叫解碼。
??????? [簡單的說去獲取一個Unicode碼就是解碼]
?code:
import java.util.*;
import java.nio.charset.*;
class CharsetTest
{
?public static void main(String[] args)throws Exception
?{
? /*
? Map m=Charset.availableCharsets();
? Set names=m.keySet();
? Iterator it =names.iterator();
? while(it.hasNext())
? {
?? System.out.println(it.next());
? }
? */
? Properties pps=System.getProperties();
? //pps.list(System.out);
? pps.put("file.encoding","ISO-8859-1");
? int data;
? byte[] buf=new byte[100];
? int i=0;
? while((data=System.in.read())!='q')
? {
?? buf[i]=(byte)data;
?? i++;
? }
? String str=new String(buf,0,i);
? //String strGBK=new String(str.getBytes("ISO-8859-1"),"GBK");
? //System.out.println(strGBK);
? System.out.println(str);
?}
}
?
???? RandomAccessFile
? RandomAccessFile類同時實現了DataInput和DataOutput接口,提供了對文件隨機存取的功能,
? 利用這個類可以在文件的任何位置讀取或寫入數據。
? RandomAccessFile類提供了一個文件指針,用來標志要進行讀寫操作的下一位數據的位置。
?
?code:
import java.io.*;
class RandomFileTest
{
?public static void main(String[] args)throws Exception
?{
? Student s1 = new Student(1,"zhangsan",98.5);
? Student s2 = new Student(2,"lisi",90.5);
? Student s3 = new Student(3,"wangwu",78.5);
?
? RandomAccessFile rsf=new RandomAccessFile("student.txt","rw");? //存取模式rw
? s1.WriteStudent(rsf);
? s2.WriteStudent(rsf);
? s3.WriteStudent(rsf);
?
? Student s =new Student();
? rsf.seek(0); //把文件指針移到文件首
? for(long i=0;i<rsf.length();i=rsf.getFilePointer())
? {
?? s.ReadStudent(rsf);
?? System.out.println(s.num+":"+s.name+":"+s.score);
? }
? rsf.close();
?}
}
class Student
{
?int num;
?String name;
?double score;
?Student()
?{
?
?}
?Student(int num,String name,double score)
?{
? this.num=num;
? this.name=name;
? this.score=score;
?}
?public void WriteStudent(RandomAccessFile raf)throws Exception
?{
? raf.writeInt(num);
? raf.writeUTF(name);
? raf.writeDouble(score);
?}
?public void ReadStudent(RandomAccessFile raf)throws Exception
?{
? raf.readInt();
? raf.readUTF();
? raf.readDouble();?
?}
}
?????????? 對象序列化
?.將對象轉換為字節流保存起來,并在日后還原這個對象,這種機制叫做對象序列化。
?.將一個對象保存到永久存儲設備上稱為持續性。
?.一個對象要想能夠實現序列化,必須實現Serializable接口或Externalizable接口。
?.當一個對象被序列化時,只保存對象的非靜態成員變量,不能保存任何的成員變量和靜態的
? 成員變量。
?.如果一個對象的成員變量是一個對象,那么這個對象的數據成員也會被保存。
?.如果一個可序列化的對象包含對某個不可序列化的對象的引用,那么整個序列化操作將會失敗,
? 并且會拋出一個NotSerializableException。我們可以將這個引用標記為transient,那么對象
? 仍然可以序列化。
?code:
import java.io.*;
class ObjectSerialTest
{
?public static void main(String[] args)throws Exception
?{
? Employee e1 = new Employee("zhangsan",20,2800.50);
? Employee e2 = new Employee("lisi",22,25000.50);
? Employee e3 = new Employee("wangwu",23,12800.50);
? Employee e4 = new Employee("blovesaga",22,3800.50);
?
? FileOutputStream fos=new FileOutputStream("employee.txt");
? ObjectOutputStream oos=new ObjectOutputStream(fos);
? oos.writeObject(e1);
? oos.writeObject(e2);
? oos.writeObject(e3);
? oos.writeObject(e4);
? oos.close();
?
? FileInputStream fis = new FileInputStream("employee.txt");
? ObjectInputStream ois =new ObjectInputStream(fis);
? Employee e;
? for(int i=0;i<4;i++)
? {
?? e=(Employee)ois.readObject();
?? System.out.println(e.name+":"+e.age+":"+e.salary);
? }
? ois.close();
?}
}
class Employee implements Serializable
{
?String name;
?int age;
?double salary;
?transient Thread t1 =new Thread();
?Employee(String name,int age,double salary)
?{
? this.name=name;
? this.age=age;
? this.salary=salary;
?}
?//可以寫private void readObject()方法來控制我們自己想要實現的
?private void writeObject(java.io.ObjectOutputStream oos)throws Exception
?{
? //例如我們自己寫想要顯示的順序和那些需要顯示
? oos.writeInt(age);
? oos.writeUTF(name);
? System.out.println("Write Object");
?}
?private void readObject(java.io.ObjectInputStream ois)throws Exception
?{
? //按照寫入的順序來讀取
? age=ois.readInt();
? name=ois.readUTF();
? System.out.println("Read Object");
?}
}