java学习笔记(十三)----IO操作
一、文件的創(chuàng)建
-------------------------------------------------------
File類(lèi),表示磁盤(pán)上的文件或目錄,可對(duì)文件或目錄進(jìn)行操作.
? * 常用方法
??? File.separator? separator用于表示目錄間的分隔符
??? creatNewFile() 創(chuàng)建一個(gè)新文件
mkdir() 創(chuàng)建一個(gè)目錄
??? delete() 可以將文件刪除
deleteonExit() 當(dāng)程序終止后刪除文件
??? createTempFile() 創(chuàng)建臨時(shí)文件
??? list() 反回當(dāng)前目錄下的所有文件名和子目錄的名字
??? isDirectory() 判斷是不是目錄
??? isFile 判是不是文件
??? FilenameFilter() 文件名的過(guò)濾器,它是個(gè)接口,
它有個(gè)方法accept(File dir,String name)返回企為值為boolean型,判斷每個(gè)文件名是不是,符合要求 ?
1. 創(chuàng)建一個(gè)文件
?? File f=new File("1.txt");
?? f.creatNewFile(); //創(chuàng)建一個(gè)名為1.txt的文件
f.mkdir(); //創(chuàng)建一個(gè)名為1.txt的目錄
2. File f=new File("E://java//abc//1.text"); //在windows下可以這么做,在linux下則不行,linux下沒(méi)有盤(pán)符
?? f.createNewFile(); 在e:/java/abc下創(chuàng)建1.text文件
?-----------------------------------------------------
3. File fDir=new File(File.separator);? //separator用于表示目錄間的分隔符,這里是表示在系統(tǒng)根目錄下
????????????????????????????????????????? 也可以 File fDir=new File(/); Windows可以這樣表示跟目錄
?? String strFile="java"+File.separator+"abc"+file.separator+"1.txt"; //? java/abc/1.txt
File f=new File(fDir,strFile); //fDir是創(chuàng)建文件的父目錄,strFile是文件位置
?? f.createNewfile();
?? f.delete() //可以將文件刪除
f.deleteonExit() //當(dāng)程序終止后刪除文件
?? Thread.sleep(3000); //3秒后程序會(huì)結(jié)束,這樣這個(gè)文件創(chuàng)建3秒后,程序結(jié)束,然后執(zhí)deleteonExit刪除文件
?--------------------------------
4. for (int i=0;i<5;i++)
?{ File f=File.createTempFile("winsun",".tmp"); //創(chuàng)建5個(gè)臨時(shí)文件,文件名是winsun,后綴名是tmp,文件位置在環(huán)境
變量的temp所指定的臨時(shí)文件的目錄下?? createTempFile是一個(gè)靜態(tài)變量,可以直接調(diào)用
?? f.deleteOnExit();
?}
?Thread.sleep(3000);
? for (int i=0;i<5;i++)
?{ File.createTempFile("winsun",".tmp"); } //可以這樣直接創(chuàng)建5個(gè)臨時(shí)文件
?---------------------------------
5. File fDir=new File(File.separator);
? String strFile="java"+File.separator+"abc"+file.separator+"aa"; //因?yàn)閘ist()顯示的目錄是從當(dāng)
前文件所在盤(pán)開(kāi)始的,所以必須
??????????????????????????????????????????????????????????????????? 從跟目錄一直找到要用到的文件目錄
?File f=new File(fDir,strFile);
?if (f.isDirectory()) //判斷是不是目錄
?{?? String[] names=f.list(); //list返回的是一個(gè)String類(lèi)型的靜態(tài)數(shù)組
???? for (int i;i<names.length;i++)
??? { System.out.println(names[i]); }
?}
?else
?{ System.out.println("沒(méi)有該目錄");
?}
------------------------------------------
6. 文件名的過(guò)濾器的用法
File fDir=new File(File.separator);
?String strFile="java"+File.separator+"abc";
?File f=new File(fDir,strFile);
?String[] names=f.list(new FilenameFilter()????? //在list()中建個(gè)文件過(guò)濾器
?{ public boolean accept(File dir,String name)
{ return name.indexOf(".java")!=-1; } // 顯示擴(kuò)展名為.java的文件,如果不等于-1返回true,否則返回flase
?}); //匿名內(nèi)部類(lèi),在查看java原文件中看到,File的list(FilenameFilter filter)方法中,自已調(diào)用了accept方法,
??????
?for (int i;i<names.length;i++)
?{ System.out.println(names[i]); }
---------------------------------------------
*********************************************
---------------------------------------------
二、文件的讀寫(xiě)
流的分類(lèi):1、節(jié)點(diǎn)流:從特定的地方讀寫(xiě)的流類(lèi),例如:磁盤(pán)或一塊內(nèi)存區(qū)域。
2、過(guò)濾流:使用節(jié)點(diǎn)流作為輸入輸出。過(guò)濾流是使用一個(gè)已經(jīng)存在的輸入流或輸出流連接創(chuàng)建的。
* InputStream
???? 三個(gè)基本的讀方法
?abstract int read() : 讀取一個(gè)字節(jié)的數(shù)據(jù),但是按整型返回的,如果返回-1表示讀到了文件流的末尾。
??????????????????????? 整型占四個(gè)字節(jié),它的第一個(gè)字節(jié)才是有效的數(shù)據(jù)(注意)
?int read(byte[] b)? :? 將數(shù)據(jù)讀入一個(gè)字節(jié)數(shù)組,同時(shí)返回實(shí)際讀取的字節(jié)數(shù)??
?int read(byte[]b,int off,int len)
其它方法
?long skip(long n): 在輸入流中跳過(guò)n個(gè)字節(jié),并返回實(shí)際跳過(guò)的字節(jié)數(shù)。
?int available(): 返回可讀取的字節(jié)數(shù)。
?void close():關(guān)閉輸入流,釋放和這個(gè)流相關(guān)的系統(tǒng)資源。
?void mark(),void reset(),booleanmarkSupported(),在這個(gè)流中都是空實(shí)現(xiàn)的方法
* ouputStream
??? 三個(gè)基本的寫(xiě)方法
?abstract void write(int b): 往輸出流中寫(xiě)入一個(gè)字節(jié),但傳進(jìn)去一個(gè)整型的數(shù)據(jù),它只寫(xiě)整型的第一個(gè)字節(jié)
?void write(byte[] b)
?void write(byte[]b,int off,int len)
??? 其它方法
?void flush(): 刷新輸出流,強(qiáng)制緩沖區(qū)中的輸出字節(jié)被寫(xiě)出。(它只對(duì)使用了緩沖的流類(lèi)起作用)
?void close():關(guān)閉輸出流
--------------------------------
System.in 和 System.out 的 in 和out 都是PrintStream類(lèi)型的
import java.io.*;
class StreamTest
{ public static void main(String[] args)throws Exception
? { int data;
??? while((data=System.in.read())!=-1)? //read它可以讀取一個(gè)字節(jié)的數(shù)據(jù),但它的返回值是一個(gè)整型,如果返回-1說(shuō)明
已經(jīng)到了流的結(jié)尾
??? { System.out.write(data);}??? //write方法的參數(shù)也是整型
?}
}
???
---------------------------------------------------
***文件輸入輸出流 FileInputStream FileOutputStream (節(jié)點(diǎn)流)***
FileOutputStream fos=new FileOutputStream("1.txt")
fos.write("http://hongxuan.ful.cn".getBytes()); //write只能寫(xiě)入一個(gè)字節(jié)或是一個(gè)字節(jié)數(shù)組,不能寫(xiě)入字符串,但它的getBytes能獲取一個(gè)字節(jié)數(shù)組
fos.close();
?FileOutputStream fos=new FileOutputStream("1.txt",true)? //后面加true是在文件后面追加
fos.write("http://hongxuan.ful.cn".getBytes());
fos.close();
?
FileInputStream fis=new FileInputStream("1.txt");
byte[] buf=new byte[100];
int len=fis.read(buf);
System.out.println(new String(buf,0,len));
fis.close();
StringBuffer s=new StringBuffer();
FileInputSteam fis=new FileInputStream();
int c;
while ((c=fis.read())!=-1)
? s.append((char)c);
System.out.println(s.toString);
?----------------------------------------
**BufferedInputStream? BufferedOutputStream () (過(guò)濾流)使用已經(jīng)存在的節(jié)點(diǎn)來(lái)構(gòu)造,提供帶緩沖的讀寫(xiě),提高了讀寫(xiě)效
率
?BufferedInputStream 真正實(shí)現(xiàn)了mark()和reset()方法
?BufferedOutputStream 實(shí)現(xiàn)了flush()方法
FileOutputStream fos=new FileOutputStream("1.txt");
BufferedOutputstream bos=new BufferedOutputStream(fos);
bos.write("http://hongxuan.ful.cn",getBytes());?? //這時(shí)1.txt中并沒(méi)有數(shù)據(jù),數(shù)據(jù)在緩充區(qū)中,因?yàn)榫彸鋮^(qū)中還沒(méi)有滿
// bos.flush();? //刷新緩充區(qū),執(zhí)行這條語(yǔ)句,就會(huì)把緩沖區(qū)中的內(nèi)容寫(xiě)到1.txt文件中
bos.close();??? //如果不加bos.flush()的話bos.close()后,也會(huì)把數(shù)據(jù)寫(xiě)到1.txt中了
FileInputStream fis=new FileInputStream("1.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
byte[] buf=new byte[100];
int len=bis.read(buf);
System.out.println(new String(buf,0,len));
bis.close();
-------------------------------
**DataInputStream 和 DataOutputStream (過(guò)濾流) 提供了讀寫(xiě)java中的基本數(shù)據(jù)類(lèi)型的功能
?
FileOutputStream fos=new FileOutputStream("1.txt");
BufferedOutputstream bos=new BufferedOutputStream(fos);
DataOutputStream dos=new DataOutputStream(bos);?? //將3個(gè)流連到一起
byte b=3; int i=78; char ch='a';? float f=4.5f;
dos.writeByte(b);
dos.writeint(b);
dos.writeChar(b);
dos.writeFloat(b);
dos.close();
FileInputStream fis=new FileInputStream("1.txt");
BufferedInputStream bis=new BufferedInputStream(fis);
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();
------------------------------------------------------
** PipedInputStream 和 PipedOutputStream (管道流,用于線程間的通信,必須同時(shí)構(gòu)造管道輸入流和管道輸出流)
*PipedInputStream的兩個(gè)構(gòu)造方法
?PipedInputStream()?
?PipedInputStream(PipedOutputStream src)
?
?PipedInputStream 的方法connect(PipedOutputStream src) 使此傳送輸入流連接到傳送輸出流 src。
?
import java.io.*;
?class PipedStreamTest
?{? public static void main(String[] args)
??? { PipedOutputStream pos=new PipedOutputStream();
????? PipedInputStream pis=new PipedInputStream();
??????????????????????????????
???????????????????????????? //在連接時(shí)會(huì)拋出個(gè)異常
????? try{ pos.connect(pis); //可以用管道輸出流連管道輸入流,也可用管道輸入流連管理輸出流
?????????????????????????????? 可定成 pis.connect(pos);??
?????????? new Produer(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 you!",getBytes());
?????? pos.close();
???? }
???? catch(Exception e)
???? { e.printStackTrace();
???? }
?? }
}
?
?Class Consumer extends Thread
?{ private PipedInputStream pis;
?? public 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(); }
?}
}
--------------------------------------------------------------
--------------------------------------------------------------
--------------------------------------------------------------
--------------------------------------------------------------
reader? writer (兩個(gè)抽象類(lèi))
InputStreamReader 從字節(jié)流到字符流的轉(zhuǎn)換
OutputStreamWriter 從字符流到字節(jié)流的轉(zhuǎn)換
?// 帶緩沖的字符流
?BufferedWriter
?BufferedReader
?//用字符流向文本文件中寫(xiě)入數(shù)據(jù)
?FileOutputStream fos=new FileOutputStream("1.txt");
?OutputStreamWriter osw=new OutputStreamWriter(fos);//將字符流轉(zhuǎn)為字節(jié)流的輸出
?BufferedWriter bw=new BufferedWriter(osw);
?bw.write("http://hongxuan.ful.cn");
?bw.close();
?
?//從文本文件中讀入數(shù)據(jù)
?FileInputStream fis=new FileInputStream("1.txt");
?InputStreamReader isr=new InputStreamReader(fis);//將字節(jié)流轉(zhuǎn)為字符流讀出
?BufferedReader br=new BufferedReader(isr);
?System.out.println(br.readLine());
?br.close();
?---------------------------
//在命令行中讀入數(shù)據(jù)然后顯示數(shù)據(jù)
?InputStreamReader isr=new InputStreamReader(System.in);
?BufferedReader br=new BufferedReader(isr);
?String StrLine;
?while((StrLine=br.readLine())!=null)
?{ System.out.println(strLine);? }
?br.close();
----------------------------------------------------------
----------------------------------------------------------
----------------------------------------------------------
****RandomAccessFile類(lèi)同時(shí)實(shí)現(xiàn)了DataInput和DataOutput接口,可以對(duì)文件隨機(jī)存取,在文件任何位置
??????????????????? 讀取或?qū)懭霐?shù)據(jù)。
??????????????????? 它有一個(gè)指針,用來(lái)進(jìn)行讀寫(xiě)操作的下一數(shù)據(jù)的位置。
寫(xiě)入一個(gè)字符串的方法
writeBytes(String s); 將一個(gè)字符的兩個(gè)字節(jié)的第一個(gè)字節(jié)寫(xiě)入到文件中,第二個(gè)字節(jié)舍棄(最好不用)
writeChars(String s); 將兩個(gè)字節(jié)表示的一個(gè)數(shù)據(jù),全都寫(xiě)入到文件中
writeUTF(String str); 英文件一般占一個(gè)字節(jié),中文是三個(gè)字節(jié),它會(huì)在寫(xiě)入數(shù)據(jù)的前面兩個(gè)字節(jié)處,記錄
寫(xiě)入數(shù)據(jù)的長(zhǎng)度,比如寫(xiě)入"myblog"這樣6個(gè)字符,它會(huì)在"myblog"前記錄個(gè)6。表明
????????????????????? "myblog"占六個(gè)字節(jié)長(zhǎng)度,對(duì)應(yīng)的有一個(gè)readUTF()?? (最好用這個(gè))
getFilePointer: 文件指針,獲取文件當(dāng)前位置
seek(long pos): 設(shè)置文件指針的偏移量,將pos設(shè)為0,文件指針就指向文件起始位置。
?
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",96.5);
??? Student s3=new Student(3,"wangwu",78.5);
??? RandomAccessFile raf=new RandomAccessFile("student.txt","rw");
??? s1.writeStudent(raf);
??? s2.writeStudent(raf);
??? s3.writeStudent(raf);
???
??? Student s=new Student();
??? raf.seek(0);
??? for (long i=0;i<raf.length();i=raf.getFilePointer()) //獲取一個(gè)文件的長(zhǎng)度,它的返回值是一個(gè)long型
??? { s.readStudent(raf);
????? System.out.println(s.num+":"+s.name+":"+s.score);
??? }
??? raf.close();
? }
}
class Student
{ int num;
? String name;
? double score;
? public Student()
? {
? }
? public Student(int num,String name,double score)
? {? this.num=num;
???? this.name=name;
???? this.score=score;
? }
? public void writeStudent(RandomAccessFile raf) throws IOException
? { raf.writeInt(num);
??? raf.writeUTF(name);
??? raf.writeDouble(score);
? }
? pubic void readStudent(RandomAccessFile raf) throws IOException
? { num=raf.readInt();
??? name=raf.readUTF();
??? score=raf.readDouble();
? }
}
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
*****對(duì)象序列化
?* 將對(duì)象轉(zhuǎn)換為字節(jié)流保存起來(lái),并在日后還原這個(gè)對(duì)象,這種機(jī)制叫做對(duì)象序列化。
?* 將一個(gè)對(duì)象保存到永久存儲(chǔ)設(shè)備上稱(chēng)為持續(xù)性。
?* 一個(gè)對(duì)象要想能夠?qū)崿F(xiàn)序列化,必須實(shí)現(xiàn)Serializable接口或Externalizable接口。
?
? Serializable接口中沒(méi)有任何方法,是個(gè)空接口,是個(gè)標(biāo)識(shí)接口,對(duì)象去實(shí)現(xiàn)這個(gè)接口,表明這個(gè)對(duì)象,可以進(jìn)行
????????????? 序列化了。
? Externalizable接口它繼承自Serializable接口
?
---實(shí)現(xiàn)對(duì)象的序列化,可利用io包中的兩個(gè)類(lèi),
?? ObjectOutputStream,它實(shí)現(xiàn)了DataOutput接口,它提供了往輸出流中寫(xiě)入java基本數(shù)據(jù)類(lèi)型的功能,
???????? ObjectOutputStream()???
???????? ObjectOutputStream(OutputStream out)
???? 它的方法,writeObject(Object obj)可以寫(xiě)入指定的對(duì)象,到對(duì)象的輸出流中,它可以完成對(duì)象的序列化。
?? ObjectInputStream,它實(shí)現(xiàn)了DataInput接口,它也提供了java基本數(shù)據(jù)類(lèi)型讀寫(xiě)的功能,
???? 它的方法,readObject()從對(duì)象輸入流中讀取一個(gè)對(duì)象。可實(shí)現(xiàn)對(duì)象的反序列化操作。
?*當(dāng)一個(gè)對(duì)象被序列化時(shí),只保存對(duì)象的非靜態(tài)成員變量,不能保存任何的成員方法和靜態(tài)的成員變量。
?*如果一個(gè)對(duì)象的成員變量是一個(gè)對(duì)象,那么這個(gè)對(duì)象的數(shù)據(jù)成員也會(huì)被保存。
?*如果一個(gè)可序列化的對(duì)象包含對(duì)某個(gè)不可序列化的對(duì)象的引用,那么整個(gè)序列化操作將會(huì)失敗,并且會(huì)拋出一個(gè)?
NotSerializableException。我們可以將這個(gè)引用標(biāo)記為transient,那么對(duì)象仍然可以序列化。
import java.io.*;
class ObjectSerialTest
{ public static void main(String[] args) throws Exception
? { Employee e1=new Employee("zhangsan",25,3000.50);
??? Employee e1=new Employee("lisi",24,3200.40);
??? Employee e1=new Employee("wangwu",27,3800.55);
???
??? FileOutputStream fos=new FileOutputStream("employee.txt");
??? ObjectOutputStream oos=new ObjectOutputStream(fos);
??? oos.writeObject(e1);
??? oos.writeObject(e2);
??? oos.writeObject(e3);
??? oos.close();
??? FileInputStream fis=new FileInputStream("employee.txt");
??? ObjectInputStream ois=new ObjectInputStream(fis);
??? Employee e;
??? for (int i=0;i<3;i++)
??? { e=(Employee)ois.readObject(); //它返回的是一個(gè)Object類(lèi)型,所以得轉(zhuǎn)換成Employee類(lèi)型
????? System.out.println(e.name":"+e.age+":"+e.salary);
??? }
? }
}
class Employee implements Serializable
{ String name;
? int age;
? double salary;?? //如果在salary前加上transient,salary這個(gè)變量也不會(huì)保存
?
? transient Thread t=new Thread(); 這里的線程對(duì)象t是個(gè)不可序列化的對(duì)象,但前面要是加個(gè)transient,
?????????????????????????????????? t這個(gè)對(duì)象就不會(huì)參與到序列化當(dāng)中.
??
? public Employee(String name,int age,double salary)
? { this.name=name;
??? this.age=age;
??? this.salary=salary;
? }
?
? //下面的兩個(gè)方法比較特殊,private的方法,一般不可以被外部調(diào)用,但下面的兩個(gè)方法,可以被調(diào)用
??? 如果想對(duì) 對(duì)象進(jìn)行控制,可以用下面的兩個(gè)方法,按自已的想法去讀寫(xiě)對(duì)象信息, 下面的這兩方法就是
在讀和寫(xiě)的時(shí)候都沒(méi)有加salary這個(gè)變量
? private void writeObject(ObjectOutputStream oos) throws IOException
? { oos.writeInt(age);
??? oos.writeUTF(name);
??? System.out.println("Write Object");
? }
? private void readObject(ObjectInputStream ois) throws IOException
? { oos.writeInt(age);
??? oos.writeUTF(name);
??? System.out.println("Read Object");
? }
}
?
?
?
總結(jié)
以上是生活随笔為你收集整理的java学习笔记(十三)----IO操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Tomcat+JSP经典配置实例
- 下一篇: java程序优化