跳到主要內容

JAVA I/O處理

 I/O處理

我們可以使用Input/Output來讀取外部的檔案/資料(檔案、console、網路資料),java.io類別庫提供很多函式功能,提供程式設計師方便使用。在JAVA SE7 會新增java.nio主要是增加io新的函式功能。

  • IO Stream 
IO分為兩種接收資料與傳送資料的模式,

(1) 位元模式(Byte Stream)
位元模式下就是輸入或是輸出資料須均要以8bit的位元,要完成一個位元模組可以利用InputStream或是OutputStream來完成。

Name: 文字檔案複製
Desc : 將文字檔複製到另一個檔案
  FileInputStream fis = null ;
OutputStream fos = null ;
try{
fis = new FileInputStream("input.txt");
fos = new FileOutputStream("output.txt") ;
  int c ;
  while((c = fis.read())!= -1){
  fos.write(c);
  }
}finally{
  if(fis!=null){
    fis.close();
  }
  if(fos!=null){
    fos.close();
}
}

(2) 字元模式(Character Streams)
字元模式主要是利用Unicode來做傳輸,當我們利用Character Stream IO做傳送時,他會自動轉成為local character的文字集,大多的應用程式都是字元模式

Name: 文字檔案複製
Desc : 將文字檔複製到另一個檔案
  FileReader rd = null ;
FileWriter rw =null ;

try{
//宣告實體
int c ;
rd = new FileReader("input.txt") ;
  rw = new FileWriter("output.txt") ;
  while((c=rd.read())!= -1){
  rw.write(c);
  }
}catch(IOException ioe){

}finally{
  if(rd!=null){
  rd.close();
}
if(rw !=null ){
rw.close();
}
}

   在常見的狀況下,我們會讀取大的資料比較常會遇到,所以IO提供以行為單位的方式來存取,我們利用緩衝的IO來實做BufferedReader,我們利用BufferedReaer的功能來實做一個簡單資料庫的功能。

Name: 簡單資料庫
Desc : 利用文字檔建立資料庫,來存取資料
 public class SimpleDataBase {
private static Map<String, String> map = new HashMap<String, String>() ;
public static void main(String[] args) throws IOException {

BufferedReader breader = null ;
BufferedWriter bwriter = null ;

try{
  breader = new BufferedReader(new FileReader("env_table.txt")) ;
  String line = "" ;
  while((line = breader.readLine())!= null){
  String value ;
  String key ;
  int index ;
  index = line.indexOf("=") ;
  key = line.substring(0, index).trim() ;
  value = line.substring(index+1, line.length()).trim() ;
  setMap(key, value);
}

System.out.println("================");
System.out.println("Color:"+getMap("color"));

}catch (Exception e) {
  System.err.println(e.toString());
}finally{
  if(breader != null){
  breader.close();
  }
  if(bwriter != null){
  bwriter.close();
  }
}
}

private static void setMap(String key, String value){
map.put(key, value);
}

private static String getMap(String key){
return map.get(key).toString();
}
}

  • BufferedReader和BufferedWriter
利用FileReader或是FileInputStream 都是直接叫OS逐一字元的讀取外部IO的資料,這種方式會造成OS系統的繁忙使效能不佳,通常會利用會先將外部資料存放在記憶體中,也稱為緩衝區(buffered IO)。
   1. BufferedReader breader = new BufferedReader(new FileReader("reader.txt"))
   2. BuffertedWriteer bwriter = new BufferedWriter(new FileWriter("writer.txt"))
  • Data Stream
資料串流是以二進位檔讀取與寫入資料,基本資料型別(int, double, float, boolean...)和字串,需要將資料以二進制排好既可,DataInputStream和DataOutputStream物件都可以支援資料型態的轉換。


    Name: BinaryDatabase資料庫
    Desc : 有一份早餐清單可以提供客人去選取,內容名稱、價錢,但是可以隨意的更動名單內容, 
              利用二元進制檔來當作早餐清單內容。

      早餐清單
    id    item      price 
     1     milk       50.0
     2     water     10.0
     3     ham       5.0
     4     egg        8.0
    public class TestDataStream {

    public class Breakfast{
    private int id ;
    private String item ;
    private double price ;

    public Breakfast(int id, String item, double price){
    this.id = id ;
    this.item = item ;
    this.price = price ;
    }
    }

    public static void main(String[] args) throws IOException {

      TestDataStream tds = new TestDataStream() ;
      //定義早餐菜單
      List<Breakfast> breakfastList = new ArrayList<>() ;
      breakfastList.add(  tds.new Breakfast( 1, "milk", 50.0));
      breakfastList.add(  tds.new Breakfast( 2, "water", 10.0));
      breakfastList.add(  tds.new Breakfast( 3, "ham", 5.0));

        //寫入早餐明細
        DataInputStream dis =null ;
        DataOutputStream dos = null ;

    try{
     System.out.println("寫入早餐明細");
     dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("breakfast.txt"))) ;

     for(int i=0 ; i< breakfastList.size() ;i++){
         Breakfast b = breakfastList.get(i) ;
        dos.writeInt(b.id);
        dos.writeUTF(b.item);
        dos.writeDouble(b.price);
     }

     //關閉文字檔
     dos.close();
     System.out.println("讀取資料");
      dis = new DataInputStream(new BufferedInputStream(new FileInputStream("breakfast.txt"))) ;
      System.out.format("%10s %10s %10s \n", "序號", "型號","價格");
      while(true){
      Breakfast b = tds.new Breakfast(dis.readInt(), dis.readUTF(), dis.readDouble()) ;
      System.out.format("%10d %10s %10f  \n", b.id, b.item , b.price );
      }
    }catch(IOException ioe){
        System.out.println(ioe.toString());
        ioe.printStackTrace();
    }finally{
      if(dos!=null){
      dos.close();
    }
        if(dos!=null){
        dis.close();
    }
    }
    }
    }


    Hot : 如果價格需要更高的精準度,需要定義BigDecimal的物件是否可以使用?
    • Object Streams
    主要的類別:ObjectOutputStream, ObjectInputStream
    主要支援物件的資料型態(Double、Bigdecimal...),但是要使用Object需要實做Serializable.

    NIO 

    現在我們討論一下何謂檔案系統,通常我們在儲存檔案時,是以階層是去存放檔案,那JAVA程式如何去知道目前的目錄的所在位置 ?
    • 了解檔案目錄結構
     每一個檔案系統都會有一個根目錄(root),在win系統下可能是C:\,linux系統下則為/ ,所以當要表達a.mp3的位置是" /音樂/a.mp3",但是如果子目錄太深每次這樣表示變成一件很繁瑣的事情,那要如何去解決這個問題? 答案: 相對路徑(Relative directory)



    • 相對路徑與絕對路徑(Relative or Absolute)
    絕對路徑就是都會以root目錄表示,
    相對路徑則會以目前的位置去表示該檔案的路徑,例如; 目前在音樂中,表達底下的音樂檔為
    a.mp3,要表達重要目錄下的檔案為"../重要/2013/01.txt"

    • 連結符號(Symbolic Links)
    在windows系統下有當你要進入快速其他資料夾,可以建立捷徑,表示它只是個連結並不有實際檔案的功能,只是方便進入其他目錄,這種連結符號在SE 7開始支援屬性的設定。

    • Path處理
    類別: Path
    Path類別使用在讀取目錄、目錄權限、轉換路徑等等的功能實現

    常用的功能 例子
    建立目錄或是檔案 Path p1 = Paths.get("/音樂/");
    Path p2 = Paths.get("/音樂/a.mp3");
    Path p3 = Paths.get(URI.create("file:///音樂"));

    取的目錄的相關資訊 Path path = Paths.get("C:\\音樂\\a.mp3");
    System.out.format("toString: %s%n", path.toString());
     System.out.format("getFileName: %s%n", path.getFileName()); System.out.format("getName(0): %s%n", path.getName(0)); System.out.format("getNameCount: %d%n", path.getNameCount()); System.out.format("subpath(0,2): %s%n", path.subpath(0,2)); System.out.format("getParent: %s%n", path.getParent()); System.out.format("getRoot: %s%n", path.getRoot());
    轉換網路目錄 Path p1 = Paths.get("C:\\Users");
     System.out.format("%s%n", p1.toUri());
    轉換為實體目錄 Path p1 = Paths.get("C:\\Users");
     System.out.println(p1.toRealPath());
    結合兩個目錄 Path p1 = Paths.get("C:\\Users");
    Path p2 = Paths.get("C:\\Users\\bryan");
    System.out.println(p1.resolve(p2));
    System.out.println(p1.resolve("Account"));
    結果:
    C:\Users\bryan
    C:\Users\Account
    Note:
    // Solaris syntax
          Path path = Paths.get("sally/bar");
     // Microsoft Windows syntax
         Path path = Paths.get("sally\\bar");

    *Glob
    *  符號表任何字串或是數字
    **  
    ? 任一字元
    {item1, item2, item3} 表示為多個字串
    [ ]  表示為一個區段,Ex: [0-9] 為0-9之間
      

    • File 檔案資訊
    File類別是用來讀取或是設定檔案資訊、目錄資訊等等,

    建構子

    Name Description
    File(File paraent, String fileName) 設定檔案名稱
    File(String pathname/path) 建立一個File實例,參數可以是檔案名稱或是路徑
    File(String path, String fileName) 第一個參數: 路徑字串 ,第二個參數:檔案字串 


    函式

    Name Description
    boolean createNewFile() 建立新檔
    static File createTempFile(String prefix, String suffix) 建立暫時檔
    static File createTempFile( String prefix, String suffix, File directory) 建立暫存檔,prefix: 檔名 , suffix:副檔名;directory:目錄
    boolean mkdir() 建立目錄
    boolean mkdirs() 建立目錄                      
    boolean exists() 檔案是否存在
    boolean renameTo( File file) 更改檔案名稱
    boolean delete() 刪除檔案
    boolean isAbsolute() 是否絕對路徑
    boolean isDirectory() 是否為目錄
    boolean isFile() 是否為檔案
    boolean isHidden() 是否為隱藏檔
    boolean isRead() 是否可讀
    boolean isWrite() 是否可寫
    String getName() 取得檔案名稱
    String  getAbsoluteFile() 取得檔案絕對路徑
    String  getAbsolutePath() 取得檔案絕對路徑
    String getPath() 取得路徑
    String getParent() 取得上層路徑
    Long length() 檔案大小
    String[] list() 回傳所有的目錄下的檔案或是目錄
    File listFiles() 回傳所有的目錄下的檔案
    long lastModified() 回傳最後修改時間



























































    留言

    這個網誌中的熱門文章

    JavaBean 和POJO

    前言 今天介紹JavaBean和POJO的不同,這兩個名詞在JAVA文章常常被拿來使用以及討論。在JDK1.1時候釋出才有的一個標準架構,很多時候常常被搞混,所以我們特別開闢一章來加以討論。POJO規範在企業級應用已經廣大的被使用的規範。 解釋 POJO : 全名為Plain-old-Java-object,只需要繼承Object就可以,沒有特定規定,只要建立的類別有setter/getter方法都可以稱為POJO JavaBean: JavaBean通常用來封裝多個物件成為單獨物件使用,規範比較嚴格,規則如下 規則 說明 1 需要實作序列(Serializable/Externalizable) 2 不能有參數的建構子( no-arg constructor) 3 需要有公用setter/getter 4 屬性必須要私人(private) 5 屬於特定POJO規則 比較 所有的JavaBean都為POJO,但是所有的POJO不一定為JavaBean 都可以當作重複元件 都必須序列化 特性都為可用性、易用性和持久化使用 - 應用 由圖我們可以知道POJO在應用程式中,主要用來存取資料庫資料達到持久化的目的,並提供給商業邏輯流程處理使用。這種POJO的架構提供程式人員開發時的可以很有規則將資料封裝並加以使用。 範例1. JavaBean(以員工為實例) JavaBean建立員工物件,可以發現Employee物件建構子沒有任何參數,屬性為私有化並setter/getter的命名方式。 //實作序列化 public class Employee implements java.io.Serializable{ private int id; private String name; //無參數建構子 public Employee(){} //以下實作setter/getter public void setId(int id){this.id=id;} public int getId(){return id;} public void setName(String ...

    GSON基礎教學

    GSON 前言 JSON是很常見的資料交換格式,在JAVA領域常用處理JSON的函式庫:GSON、FastXML和JSON-B,本章節會以GSON為主,學習目標如下 JSON格式說明 GSON 套件函式 GSON: 物件轉換JSON字串 GSON: JSON字串轉換物件 JSON 格式說明 JSON全名為JavaScript Object Notation,它是一種輕量級的資料交換格式,會大為流行的理由,主要是他比傳統用xml更輕巧且容易處理, JSON表達方式物件會用大括弧{},陣列則是用中括號[]。 用JSON字串來表達Employee的物件內容,由JSON字串可以知道物件name、age、sex和salary屬性。 JSON表示員工資料方式: {“name”:”Jack Bryant”, “age”:18, “sex”:”M”,”salary”:3500.00} JSON陣列表示方式: 跟我們使用JAVA的陣列方式類似,內容值可以是數字’、文字、布林、陣列、物件、null等等。 範例: 字串: [“紅”、”橙”、”黃”、”綠”、”青”、”藍”、”紫”} 布林: [true, true, false, false, true, true] GSON 套件函式 Gson為google所發布的函式庫,主要將物件與json字串之間的轉換時方便使用。當我們將JAVA物件轉換成JSON字串稱為 序列化 ,JSON字串轉換至JAVA物件稱為 反序列化 。 GSON: 物件轉換JSON字串 有了JSON基本概念後,我們進入本章重點,首先我們需要建立員工類別(Employee),定義如下 物件 屬性 員工類別 Employee name 名字 age 年紀 sex 性別 salary 薪水 /** * name:員工類別 */ public class Employee implements Serializable { //constructor public Employee(String name, double salary){ this.name = name; this.sala...

    H2資料庫(1)-基本安裝與介紹

    H2資料庫介紹 H2為嵌入式資料庫,使用java開發,跨平台且內含資料庫管理介面,好處開發階段方便開發人員使用。 比較 詳細比較表: http://www.h2database.com/html/features.html#comparison 由圖比較可以知道,H2比其他資料庫更為優勢,以下會介紹開發時常用的模式: 嵌入式模式Embedded Mode 嵌入式資料庫會與應用程式共用同一JVM底層,在這個模式下persistent或是in-memory資料庫都支援,也沒有連線數的限制。但壞處是只可以給該應用程式使用,其他人無法直接存取資料庫。 伺服器模式 Server Mode 外部應用程式可以藉由JDBC或是OBC的方式連結該資料庫,它也支援persistent或是in-memory資料庫,也沒有連線數的限制。 混合模式 Mixed Mode 同時有嵌入式與伺服器的模式去讓外部應用程式連線或是自己應用程式連線。 安裝H2 database 官方網站: http://www.h2database.com/html/main.html 下載安裝程式 出現安裝連結,本次範例使用 Windows installer 的安裝連結 下載安裝程式後,點擊兩下,進入安裝畫面,按”下一步” 一直按”下一步”後,會出現”完成” 安裝完成後,會出現一個說明網頁,你可以點選Quickstart 它會告訴你,如何進入DBRMS畫面以及開啟資料庫服務 開啟windows的視窗圖示,執行 H2 Console後,會執行H2資料庫 進入DBRMS的登入畫面,使用者預設為”SA”,密碼為空值”“,按下”connect”進入,SQL命令中心 登入後,可以在空白處執行SQL語法 8.大致上安裝H2資料庫滿快速,操作畫面也是很好上手,如果系統在開發階段個人覺的滿推薦給大家使用看看。 參考 H2官方網站