④Java.IO

java.IO包是java處理文件目錄有關的工具包,對于本節的學習,我們要有以下幾個目標

  • 了解java.io包
  • 運用File類對文件或者目錄的屬性進行操作
  • 理解流,理解輸入輸出流的概念
  • 運用FileInputStream類和FileOutputStream類讀、寫字節文件
  • 運用FileReader類和FileWriter類配合BufferedReader類和BufferedWriter類讀、寫字符文件。
  • 使用BufferedReader類從控制臺接受輸入
  • 運用DataInputStream類和DataOutputStream類讀寫數據文件

這里十分感謝:http://blog.csdn.net/nisior/article/details/7162754

首先來了解File類

顧名思義看來,就是文件,這個類包含了文件的屬性包括路徑、名稱、大小等等,如果在處理文件的時候需要用到某種屬性或者方法,一定要到File類來看看是否有你想要的東西。

注:學習應該也是應該以網絡的形式展開,你需要做的是拓展網絡節點的個數,每個節點代表了一個知識點,實踐的時候再去拓展這個節點,形成一個子網絡。

至于File類中的方法,希望諸君不要像我一樣偷懶,一定要瀏覽一遍。這里舉個例子以饗讀者:

public class FileDemo
{
public static void main(String[] args)
{
    //創建一個文件對象,使之與一個文件關聯
    File file = new File("File.txt");

    //顯示與文件有關的屬性信息
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());
    }
}
再來看看流的概念

流是指一連串流動的數據信號,是以先進先出的方式發送和接收數據的通道。

流示意圖
流示意圖

流示意圖
流示意圖

根據流動的方向,分為輸入流和輸出流

根據文件的大小,分為字節流和字符流

字節流:是指8位的通用字節流,以字節為基本單位,對字節流進行操作的類大多繼承于InputStream和OutputStream類。

字符流:是指16位的Unicode字符流,以字符(兩個字節)為基本單位,非常適合處理字符串和文本,大部分繼承自Reader類和Writer類。

下面我們來看看這個包中最常見的方法,也是你們今后用到的最頻繁的方法:

使用FileInputStream類讀文件
  • FileInputStream類成為文件輸入流,繼承于InputStream類,是文件操作的最基本的類
  • 它的作用是將文件中的數據輸入到內存中,我們可以利用它來讀文件
  • 由于它屬于字節流,因此在讀取Unicode字符(如中文)的文件時候可能會出現問題
使用FileOutputStream類寫文件
  • 繼承自OutputStream類,可以利用它來寫文件。

一般來講,這兩個類的使用是成對出現的,采用字節來處理文件,好處就在于,不必考慮數據格式的問題,雖然在編碼上稍微復雜了一些,但是當文件過大的時候,效率就體現出來了。

public class CopyFileDemo {
public static void main(String[] args) throws IOException {
File srcFile = new File("src.dat");    //源文件對象
File destFile = new File("dest.dat");  //目標文件對象
if (!(destFile.exists())) {  //判斷目標文件是否存在
  destFile.createNewFile();  //如果不存在則創建新文件
}
//使用源文件對象創建文件輸入流對象
FileInputStream fis = new FileInputStream(srcFile);
//使用目標文件對象創建文件輸出流對象
FileOutputStream fos = new FileOutputStream(destFile);
byte[] buf = new byte[1024];  //創建字節數組,作為臨時緩沖
System.out.println("開始復制文件...");
while (fis.read(buf) != -1) {  //循環從文件輸入流中讀取數據
  fos.write(buf);    //寫入到文件輸出流中
}
System.out.println("文件復制成功!");
fis.close();    //關閉流
fos.close();

}
}

字符流

? FileInputStram類和FileOutputStream類雖然可以高效率地讀/寫文件,但對于Unicode編碼的文件,使用它們有可能出現亂碼;

? 考慮到Java是跨平臺的語言,要經常操作Unicode編碼的文件,使用字符流操作文件是有必要的;

? 使用字符流將涉及到以下4個類:

FileReader類和FileWriter類;

BufferedReader類和BufferedWriter類。

這四個類你非常容易用到,不要再被各種名稱搞混淆,其核心就這么幾句話:
讀寫類要用Buffer類包裝,任何的讀寫都要設置緩存才能實現高效。

可以將這段代碼作為例子仔細的研讀一番

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();
}

}

到目前位置我們已經介紹了兩種流,字符和字節,這兩種流之間還有過渡流,即:
InputStreamReader, InputStreamWriter
他們是字節流和字符流的橋梁,作用是人為的操作格式編碼。

設想這么一種情況:
當你使用System.in 從控制臺接受輸入的時候,由于in是一個InputStream類型的對象,所以你每一次只能從控制臺輸入一個字節才不會引起錯誤,所以必須對in進行處理,才可以順利的從控制臺接受輸出,所以將使用:
 InputStreamReader
 BufferedReader
 
?可以使用它來轉換System.in,如:
InputStreamReader isr = new InputStreamReader(System.in);
?這樣的字符流效率很低,再使用BufferedReader類來為其建立緩沖,如:
BufferedReader br = new BufferedReader(isr);
?這樣,就可以從控制臺接受輸入了。
基本數據類型的讀/寫

?FileInputStream和FileOutputStream在讀寫文件時不考慮數據的類型;
?FileWriter和FileReader在讀寫文件時,將所有的數據都看做字符;
?有時候,我們需要將各種類型的數據寫入文件或是從文件中讀取,

DataInputStream類和DataOutputStream類可以滿足需要。

但是它們不能單獨使用,需要配合別的字節流一起使用。

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中的對象存入到我們要求的儲存介質中去,可以用來做數據緩存。
處理的對象都必須實現Serializable,transiant關鍵字來修飾無需序列化的屬性

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:隨機文件讀取

使用場景:支持對隨機訪問文件的讀取和寫入
特點:

  • 類中既有讀方法也有寫方法

  • 必須指定訪問文件模式

  • 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();
    
}

}

總結

? java.io包是Java內置的包,其中包含一系列對輸入/輸出進行操作的類;

? File類的對象可以訪問文件(或目錄)的屬性,但不可以進行讀/寫操作;

? 從方向上講,流分為輸入流和輸出流,但從格式上區分的話,流分為字節流和字符流;

? 使用FileInputStream類和FileOutputStream類以字節流方式對文件進行讀/寫操作,這是操作文件最基本的兩個類;

? FileReader類和FileWriter類配合BufferedReader類和BufferedWriter類可以以字符流方式對文件進行讀/寫操作;

? 從控制臺接受輸入要使用到InputStreamReader類和BufferedReader類;

? DataInputStream類和DataOutputStream類允許讀/寫各種基本數據類型;

? 絕大部分的IO操作都可能拋出IOException。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • tags:io categories:總結 date: 2017-03-28 22:49:50 不僅僅在JAVA領...
    行徑行閱讀 2,210評論 0 3
  • 一、流的概念和作用。 流是一種有順序的,有起點和終點的字節集合,是對數據傳輸的總成或抽象。即數據在兩設備之間的傳輸...
    布魯斯不吐絲閱讀 10,101評論 2 95
  • 標準輸入輸出,文件的操作,網絡上的數據流,字符串流,對象流,zip文件流等等,java中將輸入輸出抽象稱為流,就好...
    navy_legend閱讀 727評論 0 0
  • 懷孕已近乎五個月了,前三個月的痛苦幾乎消失殆盡。最近在吃吃喝喝中無法自拔,體重直線飆升,當然,每天還有寶貝的胎動...
    碧海穎天閱讀 340評論 1 1