java.IO包是java處理文件目錄有關(guān)的工具包哺哼,對于本節(jié)的學(xué)習(xí),我們要有以下幾個(gè)目標(biāo)
- 了解java.io包
- 運(yùn)用File類對文件或者目錄的屬性進(jìn)行操作
- 理解流园欣,理解輸入輸出流的概念
- 運(yùn)用FileInputStream類和FileOutputStream類讀帖世、寫字節(jié)文件
- 運(yùn)用FileReader類和FileWriter類配合BufferedReader類和BufferedWriter類讀、寫字符文件沸枯。
- 使用BufferedReader類從控制臺接受輸入
- 運(yùn)用DataInputStream類和DataOutputStream類讀寫數(shù)據(jù)文件
這里十分感謝:http://blog.csdn.net/nisior/article/details/7162754
首先來了解File類
顧名思義看來狮暑,就是文件,這個(gè)類包含了文件的屬性包括路徑辉饱、名稱、大小等等拣展,如果在處理文件的時(shí)候需要用到某種屬性或者方法彭沼,一定要到File類來看看是否有你想要的東西。
注:學(xué)習(xí)應(yīng)該也是應(yīng)該以網(wǎng)絡(luò)的形式展開备埃,你需要做的是拓展網(wǎng)絡(luò)節(jié)點(diǎn)的個(gè)數(shù)姓惑,每個(gè)節(jié)點(diǎn)代表了一個(gè)知識點(diǎn),實(shí)踐的時(shí)候再去拓展這個(gè)節(jié)點(diǎn)按脚,形成一個(gè)子網(wǎng)絡(luò)于毙。
至于File類中的方法,希望諸君不要像我一樣偷懶辅搬,一定要瀏覽一遍唯沮。這里舉個(gè)例子以饗讀者:
public class FileDemo
{
public static void main(String[] args)
{
//創(chuàng)建一個(gè)文件對象脖旱,使之與一個(gè)文件關(guān)聯(lián)
File file = new File("File.txt");
//顯示與文件有關(guān)的屬性信息
System.out.println("文件或目錄是否存在:" + file.exists());
System.out.println("是文件嗎:" + file.isFile());
System.out.println("是目錄嗎:" + file.isDirectory());
System.out.println("名稱:" + file.getName());
System.out.println("絕對路徑:" + file.getAbsolutePath());
System.out.println("文件大小:" + file.length());
}
}
再來看看流的概念
流是指一連串流動的數(shù)據(jù)信號介蛉,是以先進(jìn)先出的方式發(fā)送和接收數(shù)據(jù)的通道萌庆。
根據(jù)流動的方向,分為輸入流和輸出流
根據(jù)文件的大小币旧,分為字節(jié)流和字符流
字節(jié)流:是指8位的通用字節(jié)流践险,以字節(jié)為基本單位,對字節(jié)流進(jìn)行操作的類大多繼承于InputStream和OutputStream類吹菱。
字符流:是指16位的Unicode字符流巍虫,以字符(兩個(gè)字節(jié))為基本單位,非常適合處理字符串和文本鳍刷,大部分繼承自Reader類和Writer類占遥。
下面我們來看看這個(gè)包中最常見的方法,也是你們今后用到的最頻繁的方法:
使用FileInputStream類讀文件
- FileInputStream類成為文件輸入流倾剿,繼承于InputStream類筷频,是文件操作的最基本的類
- 它的作用是將文件中的數(shù)據(jù)輸入到內(nèi)存中,我們可以利用它來讀文件
- 由于它屬于字節(jié)流前痘,因此在讀取Unicode字符(如中文)的文件時(shí)候可能會出現(xiàn)問題
使用FileOutputStream類寫文件
- 繼承自O(shè)utputStream類凛捏,可以利用它來寫文件。
一般來講芹缔,這兩個(gè)類的使用是成對出現(xiàn)的坯癣,采用字節(jié)來處理文件,好處就在于最欠,不必考慮數(shù)據(jù)格式的問題示罗,雖然在編碼上稍微復(fù)雜了一些,但是當(dāng)文件過大的時(shí)候芝硬,效率就體現(xiàn)出來了蚜点。
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
File srcFile = new File("src.dat"); //源文件對象
File destFile = new File("dest.dat"); //目標(biāo)文件對象
if (!(destFile.exists())) { //判斷目標(biāo)文件是否存在
destFile.createNewFile(); //如果不存在則創(chuàng)建新文件
}
//使用源文件對象創(chuàng)建文件輸入流對象
FileInputStream fis = new FileInputStream(srcFile);
//使用目標(biāo)文件對象創(chuàng)建文件輸出流對象
FileOutputStream fos = new FileOutputStream(destFile);
byte[] buf = new byte[1024]; //創(chuàng)建字節(jié)數(shù)組,作為臨時(shí)緩沖
System.out.println("開始復(fù)制文件...");
while (fis.read(buf) != -1) { //循環(huán)從文件輸入流中讀取數(shù)據(jù)
fos.write(buf); //寫入到文件輸出流中
}
System.out.println("文件復(fù)制成功拌阴!");
fis.close(); //關(guān)閉流
fos.close();
}
}
字符流
? FileInputStram類和FileOutputStream類雖然可以高效率地讀/寫文件绍绘,但對于Unicode編碼的文件,使用它們有可能出現(xiàn)亂碼迟赃;
? 考慮到Java是跨平臺的語言陪拘,要經(jīng)常操作Unicode編碼的文件,使用字符流操作文件是有必要的纤壁;
? 使用字符流將涉及到以下4個(gè)類:
FileReader類和FileWriter類左刽;
BufferedReader類和BufferedWriter類。
這四個(gè)類你非常容易用到酌媒,不要再被各種名稱搞混淆欠痴,其核心就這么幾句話:
讀寫類要用Buffer類包裝迄靠,任何的讀寫都要設(shè)置緩存才能實(shí)現(xiàn)高效。
可以將這段代碼作為例子仔細(xì)的研讀一番
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;
public class Test11 {
public static void main(String[] args) throws IOException {
String s="abcd中國家@#$%"+System.getProperty("line.separator")+"asdfsdf順右面";
Test11 t=new Test11();
t.writeFile(s);
t.readFile();
}
public void readFile() throws IOException{
File f=new File("r:\\io\\reader.doc");
FileReader fr=new FileReader(f);
BufferedReader br=new BufferedReader(fr);
String ss=null;
while((ss=br.readLine())!=null){
System.out.println(ss);
}
br.close();
fr.close();
}
public void writeFile(String s) throws IOException{
File f=new File("r:\\io\\reader.doc");
FileWriter fr=new FileWriter(f);
BufferedWriter br=new BufferedWriter(fr);
br.write(s);
br.close();
fr.close();
}
}
到目前位置我們已經(jīng)介紹了兩種流斋否,字符和字節(jié)梨水,這兩種流之間還有過渡流,即:
InputStreamReader, InputStreamWriter
他們是字節(jié)流和字符流的橋梁茵臭,作用是人為的操作格式編碼疫诽。
設(shè)想這么一種情況:
當(dāng)你使用System.in 從控制臺接受輸入的時(shí)候,由于in是一個(gè)InputStream類型的對象旦委,所以你每一次只能從控制臺輸入一個(gè)字節(jié)才不會引起錯(cuò)誤奇徒,所以必須對in進(jìn)行處理,才可以順利的從控制臺接受輸出缨硝,所以將使用:
InputStreamReader
BufferedReader
?可以使用它來轉(zhuǎn)換System.in摩钙,如:
InputStreamReader isr = new InputStreamReader(System.in);
?這樣的字符流效率很低,再使用BufferedReader類來為其建立緩沖查辩,如:
BufferedReader br = new BufferedReader(isr);
?這樣胖笛,就可以從控制臺接受輸入了。
基本數(shù)據(jù)類型的讀/寫
?FileInputStream和FileOutputStream在讀寫文件時(shí)不考慮數(shù)據(jù)的類型宜岛;
?FileWriter和FileReader在讀寫文件時(shí)长踊,將所有的數(shù)據(jù)都看做字符;
?有時(shí)候萍倡,我們需要將各種類型的數(shù)據(jù)寫入文件或是從文件中讀取身弊,
DataInputStream類和DataOutputStream類可以滿足需要。
但是它們不能單獨(dú)使用列敲,需要配合別的字節(jié)流一起使用阱佛。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class Test8 {
public static void main(String[] args) throws Exception {
File f = new File("r:\\io\\dat.dat");
FileOutputStream fos = new FileOutputStream(f);
DataOutputStream dos = new DataOutputStream(fos);
dos.write(22);
dos.writeBoolean(true);
dos.writeChar('a');
dos.writeUTF("abc中國家####");
dos.close();
fos.close();
FileInputStream fis=new FileInputStream(f);
DataInputStream dis=new DataInputStream(fis);
System.out.println( dis.read());
System.out.println( dis.readBoolean());
}
}
ObjectInputStream ObjectOutputStream
作用:用來處理Object對象的流,能將原來只能存于VM中的對象存入到我們要求的儲存介質(zhì)中去戴而,可以用來做數(shù)據(jù)緩存凑术。
處理的對象都必須實(shí)現(xiàn)Serializable,transiant關(guān)鍵字來修飾無需序列化的屬性
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Test9 {
public static void main(String[] args) throws Exception {
File f = new File("r:\\io\\dat2.dat");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream dos = new ObjectOutputStream(fos);
Person p=new Person("yy",22);
dos.writeObject(p);
dos.close();
fos.close();
FileInputStream fis=new FileInputStream(f);
ObjectInputStream ois=new ObjectInputStream(fis);
Person ps=(Person)ois.readObject();
System.out.println(ps.getName()+"\t"+ps.getId());
}
}
class Person implements Serializable{
private String name;
private transient int id;
public Person() {
super();
}
public Person(String name, int id) {
super();
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
RandomAccessFile:隨機(jī)文件讀取
使用場景:支持對隨機(jī)訪問文件的讀取和寫入
特點(diǎn):
類中既有讀方法也有寫方法
必須指定訪問文件模式
-
seek()和skip()
示例:操作日志import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test10 {
public static void main(String[] args) throws IOException {
BankAccount ba=new BankAccount(1000);
for(int i=0;i<10;i++){
ba.withDrawal(100);
}
}
}
class BankAccount{
private int money;
public BankAccount(int money){
this.money=money;
}
public void withDrawal(int money) throws IOException{
this.money=this.money-money;
log("您取了"+money+",賬戶余額:"+this.money);
}
private void log(String string) throws IOException {
File f=new File("r:\\io\\log.txt");
RandomAccessFile raf=new RandomAccessFile(f,"rwd");
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
Date d=new Date();
String dd=sdf.format(d);
raf.seek(raf.length());
String s="\r\n"+dd+"\t"+string;
raf.write(s.getBytes("gbk"));
raf.close();
}
}
總結(jié)
? java.io包是Java內(nèi)置的包所意,其中包含一系列對輸入/輸出進(jìn)行操作的類淮逊;
? File類的對象可以訪問文件(或目錄)的屬性,但不可以進(jìn)行讀/寫操作扁眯;
? 從方向上講,流分為輸入流和輸出流翅帜,但從格式上區(qū)分的話姻檀,流分為字節(jié)流和字符流;
? 使用FileInputStream類和FileOutputStream類以字節(jié)流方式對文件進(jìn)行讀/寫操作涝滴,這是操作文件最基本的兩個(gè)類绣版;
? FileReader類和FileWriter類配合BufferedReader類和BufferedWriter類可以以字符流方式對文件進(jìn)行讀/寫操作胶台;
? 從控制臺接受輸入要使用到InputStreamReader類和BufferedReader類;
? DataInputStream類和DataOutputStream類允許讀/寫各種基本數(shù)據(jù)類型杂抽;
? 絕大部分的IO操作都可能拋出IOException诈唬。