Java學習筆記之檔案

左墾發表於2017-05-11

一.檔案類
1.File類
檔案和目錄路徑的抽象表達形式
1.1構造方法
·File(String pathname):把一個路徑名稱封裝成File物件
·File(String parent, String child):把一個父路徑和一個子路徑封裝成一個File物件
·File(File parent, String child):把一個父路徑File物件和一個子路徑封裝成一個File物件
1.2建立功能
A:建立檔案
public boolean createNewFile():如果檔案不存在,就建立。否則,不建立。
需求:D盤下造一個檔案a.txt
import java.io.File;
import java.io.IOException;

        public class CreatFileDemo {
            public static void main(String[] args) throws IOException {
                File file = new File("D://a.txt");
                System.out.println(file.createNewFile());
            }
        }
    B:建立目錄
        public boolean mkdir():如果目錄不存在,就建立。否則,不建立。
        需求:D盤下造一個資料夾test
        import java.io.File;

        public class CreatDemo2 {
            public static void main(String[] args) {
                File file = new File("D://test");
                System.out.println(file.mkdir());
            }
        }
        public boolean mkdirs():如果目錄不存在,就建立。否則,不建立。
                                即時父目錄不存在,也可以連父目錄一起建立。
1.3刪除功能:
public boolean delete():既可以刪除檔案,又可以刪除目錄。且當有此語句是先執行此語句
                        注意:A:Java程式的刪除不走回收站。
                              B:如果目錄內還有內容就不能刪除。
1.4路徑問題:
    A:絕對路徑  就是以碟符開始的路徑(d:\\test\\aaa\\b.txt)
    B:相對路徑  就是不以碟符開始的路徑(a.txt)
                一般都是相對應當前的專案而言的。
1.5
  判斷功能
  public boolean isDirectory():是否是目錄
  public boolean isFile():是否是檔案
  public boolean exists():是否存在
  public boolean canRead():是否可讀
  public boolean canWrite():是否可寫
  public boolean isHidden():是否隱藏


1.6獲取功能
  public String getAbsolutePath():獲取絕對路徑
  public String getPath():獲取相對路徑
  public String getName():獲取名稱

二.位元組流和位元組高效流
2.1 I/O流分類
按流向分可分為輸入流和輸出流;按資料型別分可分為位元組流和字元流,位元組流又可分為位元組輸入流(InputStream抽象類)和位元組輸出流(OutputStream抽象類);字元流可分為字元輸入流(Reader)和字元輸出流(Wirter)
2.2
針對以上舉個例子是說明
需求:請用位元組流往一個文字檔案中寫一句話:”helloworld”。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

    public class FileOutput {
        public static void main(String[] args) throws Exception {
            FileOutputStream fos = new FileOutputStream("D://a.txt");//建立檔案
            fos.write("HelloWorld".getBytes());//寫入檔案內容
            fos.close();//關流
        }
    }
2.3
在上面的程式碼中FileOutputStream是OutputStream的子類,由於OutputSteam是抽象類,所以我們必須使用多型的方式來是想它的具體功能,相應的InputStream的子類是FileInputStream
它們具有對稱的方法:
                    FileOutputStream寫資料的方法
                    write(byte[] b) 
                    write(int b) :一次寫一個位元組
                    write(byte[] b, int off, int len) :一次寫一個位元組陣列的一部分
2.4
    對於位元組輸入流和字元輸出流有一定的操作流程,以字元輸入流為例:
         * 位元組輸入流操作步驟:
         * A:建立位元組輸入流物件
         FileInputStream  fis = new FileInputStream("a.txt");

         * B:呼叫方法讀取資料(一次讀取一個位元組陣列,提升效率)
         一次讀取一個位元組陣列: public int read(byte[] b):返回實際讀取長度,資料被讀取到陣列中。
         -- 測試方法返回長度?根據String類的構造方法構造字串
         * C:釋放資源
         fis.close
        舉個例子:
        1.一次複製一個位元組
            import java.io.FileInputStream;
            import java.io.FileNotFoundException;
            import java.io.FileOutputStream;

            //A:把a.txt的內容複製到b.txt中

            public class CopyFileDemo {
                public static void main(String[] args) throws Exception {
                    FileInputStream fis = new FileInputStream("D://a.txt");
                    FileOutputStream fos = new FileOutputStream("b.txt");

                    int byt;
                    while((byt = fis.read()) != -1){
                        fos.write(byt);
                        System.out.print((char)byt);
                    }

                    fos.close();
                    fis.close();
                }
            }

        2.一次複製一個位元組陣列
            import java.io.FileInputStream;
            import java.io.FileNotFoundException;
            import java.io.FileOutputStream;

            public class CopyFileDemo2 {
                public static void main(String[] args) throws Exception {
                    FileInputStream fis = new FileInputStream("D://b.mp4");
                    FileOutputStream fos = new FileOutputStream("c.mp4");

                    byte[] chs = new byte[1024];
                    int len;
                    while((len = fis.read(chs)) != -1){
                        fos.write(chs, 0, len);
                    }

                    fos.close();
                    fis.close();

                }
            }
2.5
    位元組緩衝區流(也叫高效流):
    BufferedInputStream(read() 一次讀取一個位元組, public int read(byte[] b):返回實際讀取長度,資料被讀取到陣列中。)
    BufferedOutputStream(write(byte[] b)) 

    流:
    低階流: 基本的流,可以直接操作檔案。
    高階流:是操作基本流的流。

    A:高效位元組流一次讀寫一個位元組     
        並計算時間

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;

    public class BufferedDemo {
        public static void main(String[] args) throws IOException {
            long startTime = System.currentTimeMillis();

            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D://b.mp4"));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d.mp4"));

            int byt;
            while((byt = bis.read()) != -1){
                bos.write(byt);
            }

            bos.close();//關流
            bis.close();

            long endTime = System.currentTimeMillis();
            System.out.println(endTime-startTime + "ms");
        }
    }
    B:高效位元組流一次讀寫一個位元組陣列,並計算時間
        import java.io.BufferedInputStream;
        import java.io.BufferedOutputStream;
        import java.io.FileInputStream;
        import java.io.FileNotFoundException;
        import java.io.FileOutputStream;
        import java.io.IOException;

        public class BufferedDemo2 {
            public static void main(String[] args) throws IOException {
                long startTime = System.currentTimeMillis();

                BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D://b.mp4"));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e.mp4"));

                byte[] byt = new byte[1024];
                int len;
                while((len = bis.read(byt)) != -1){
                    bos.write(byt, 0, len);
                }

                bos.close();//關流
                bis.close();

                long endTime = System.currentTimeMillis();
                System.out.println(endTime-startTime + "ms");
            }
        }
2.6
    編碼問題:在java中預設的編碼方式是GBK,還有另一種是UTF-8。兩者之間需要我們手動切換,切記一點,用什麼編碼就要用什麼解碼
    所謂編碼就是把我們能夠看得懂的字元轉換蔚看不懂的;解碼就是把我們看不懂的轉換為我們可以看懂的

三.字元流和字元高效流
Reader(抽象類):用於讀取字元流的抽象類。子類必須實現的方法只有read(char[], int, int)和close(),但多數子類將重寫更多的方法以提供更高的效率
Wirter(抽象類):寫入字元流的抽象類,必須重寫的方法有write(char[], int, in ),flush(),close()方法,但是多數子類將重寫更多的方法,以得到更高的效率和功能
1.1位元組流和符流
OutputStreamWriter:是字元流通向位元組流的橋樑:可使用指定的charset將要寫入流中的字元編碼成位元組。它使用的字符集可以由名稱指定或顯式給定,否則將接受平臺預設的字符集。
InputStreamReader:是位元組流通向字元流的橋樑:它使用指定的charset讀取位元組並將其解碼為字元。它使用的字符集可以由名稱指定或顯式給定,或者可以接受平臺預設的字符集。

    寫入資料,把位元組輸出流轉換為字元輸出流(不指定碼錶)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"));

    把位元組輸出流轉換為字元輸出流(指定碼錶)
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt", "GBK"));     

    讀取資料, 把位元組輸入流轉換為字元輸入流(不指定碼錶)
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
    把位元組輸入流轉換為字元輸入流(指定碼錶)
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt", "GBK")); 

    總結:我們一般建立字元輸入或者輸出流一般情況下使用系統預設的碼錶就可以,如果來來回回需要指定碼錶的話,就顯得非常的麻煩了
1.2構造方法
    FileWriter(File file) 
    FileWriter(String fileName) 
    FileReader(File file) 
    FileReader(String fileName)
這裡需要注意一下FileWriter中的方法flush()和close()的區別? 
    * A:flush   重新整理緩衝區,流物件可以繼續
    * B:close   先重新整理緩衝區,再關閉流物件。流物件不可以繼續使用了。
練習上述問題:
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;

    public class FileWriterDemo {
        public static void main(String[] args) throws IOException {
            FileWriter fw = new FileWriter(new File("e.txt"));
            fw.write("假如生活欺騙了你,不要悲傷,不要難過,憂鬱的日子將會過去,快樂的日子將會來臨");
            fw.flush();
            fw.close();
        }
    }
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;

    public class FileReaderDemo {
        public static void main(String[] args) throws IOException {
            FileReader fi = new FileReader(new File("e.txt"));
            int ch;
            while ((ch=fi.read())!=-1) {
                System.out.print((char)ch);
            }
        /*  char[] cha = new char[1024];
            int len;
            while((len = fi.read(cha)) != -1){
                System.out.print(new String(cha, 0, len));
            } */

            fi.close();
        }
    }
1.3高效流(更多方法可查閱API)
 * BufferedReader:字元緩衝輸入流
 構造:BufferedReader(Reader in) 
 特殊方法:public String readLine():包含該行內容的字串,不包含任何行終止符,如果已到達流末尾,則返回 null 

 * BufferedWriter:字元緩衝輸出流
 構造:BufferedWriter(Writer out) 
 特殊方法:public void newLine():會根據系統來確定寫入不同的換行符
    利用字元高效流的一次讀寫一行的特性複製檔案
    寫資料注意三部曲:
        bw.write(line);
        bw.newLine();
        bw.flush();
    針對上述的知識點,可以通過一個練習鍵盤錄入5個學生資訊(姓名,語文成績,數學成績,英語成績),按照總分從高到低存入文字檔案

四.設計模式(瞭解)
A:設計模式概述
設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。
使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性以及程式碼的結構更加清晰.

B:設計模式分類
    建立型模式(建立物件的):   單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。
    行為型模式(物件的功能):   介面卡模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。
    結構型模式(物件的組成):   模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、
    直譯器模式、狀態模式、策略模式、職責鏈模式、訪問者模式。


    單例設計模式(掌握)
    A:單例設計思想
        保證類在記憶體中只有一個物件
    B:如何實現類在記憶體中只有一個物件呢?
        構造私有
        本身提供一個物件
        通過公共的方法讓外界訪問
    C:案例演示: 單例模式之餓漢式

    問題:面試中寫哪種設計模式呢?

    工廠設計模式(掌握)
(簡單工廠模式概述和使用)(理解)
A:簡單工廠模式概述: 又叫靜態工廠方法模式,它定義一個具體的工廠類負責建立一些類的例項
B:優點:   使用靜態工廠模式的優點是實現責任的分割,該模式的核心是工廠類,工廠類含有必要的選擇邏輯,可以決定什麼時候建立哪一個產品的例項,
        而客戶端則免去直接建立產品的責任,而僅僅是消費產品。也就是說靜態工廠模式在不改變客戶端程式碼的情況可以動態的增加產品。
        明確了類的職責
C:缺點
    這個靜態工廠類負責所有物件的建立,如果有新的物件增加,或者某些物件的建立方式不同,
    就需要不斷的修改工廠類,不利於後期的維護
D:案例演示


(抽象工廠模式的概述和使用)(理解)
A:工廠方法模式概述
    工廠方法模式中抽象工廠類負責定義建立物件的介面,具體物件的建立工作由繼承抽象工廠的具體類實現。
B:優點
    客戶端不需要在負責物件的建立,從而明確了各個類的職責,如果有新的物件增加,
    只需要增加一個具體的類和具體的工廠類即可,不影響已有的程式碼,後期維護容易,增強了系統的擴充套件性
C:缺點:   需要額外的編寫程式碼,增加了工作量

五.異常
1.1
異常:就是程式出現的不正常的情況。

舉例:

異常:
錯誤:這是非常嚴重的問題,一般我們處理不了,一般在這裡指的是硬體問題。
異常:
編譯時期異常 開始就必須要處理的,如果不處理,後面就走不了。
執行時期異常 開始可以不用處理。這種問題一旦發生,就是我們的程式問題,需要我們修改程式。

體系結構:
Throwable:
Error:
Exception:
非RuntimeException:編譯時期異常
RuntimeException:執行時期異常

異常演示:
除數不能為0

java.lang.ArithmeticException: / by zero

針對異常,JVM預設的處理方案:
一旦遇到程式出現了問題,就會把問題的類名,錯誤原因,錯誤的位置等資訊列印在控制檯,以便我們觀察。
並且,會自動從當前出問題的地方停止掉。

這種處理方案雖然可以,但是不夠好。
哪裡不好呢?
其實程式出問題,不應該直接停止,因為我們的程式可能是由多部分組成的,
其中一個部分出問題了,不應該影響其他部分的執行。
所以,我們應該想辦法讓其他的部分能夠執行下去。
1.2

我們是如何處理異常,保證各個部分不影響的呢?
兩種方案:
A:try…catch…finally
B:throws

try…catch…finally:
try{
可能出現異常的程式碼
}catch(異常類名 變數名) {
針對異常的程式碼處理
}finally {
釋放資源的地方
}

我們簡化一下第一個:
try{
可能出現異常的程式碼
}catch(異常類名 變數名) {
針對異常的程式碼處理
}
1.3
多個異常的處理(演示陣列索引越界異常,除數為0異常)
A:針對每一個出現問題的地方寫一個try…catch語句
B:針對多個異常,採用一個try,多個catch的情況。
try…catch…catch…

    遇到try裡面的問題,就自動和catch裡面進行匹配。
    一旦匹配就執行catch裡面的內容,執行完畢後,接著執行後面的程式碼。

    注意:
        如果異常間有子父關係,父必須在最後。

1.4
編譯時期異常和執行時期異常的區別:
編譯時期異常:Java程式必須顯示處理,否則程式就會發生錯誤,無法通過編譯
FileNotFoundException(檔案未找到異常)
執行時期異常:無需顯示處理,也可以和編譯時異常一樣處理
ArithmeticException
1.5
Throwable中的方法:(演示除數為0異常)
rintStackTrace():列印異常資訊,程式從出問題的地方開始就會列印建立一個該異常對應的物件,
該物件直接呼叫列印方法

1.6(演示編譯器異常,執行期異常)
try…catch 是直接進行了處理。
而throws則是把異常處理的事情交給了呼叫者。

throws用在方法上,宣告方法有異常,交給呼叫者處理。
但是呢,如果是編譯時期異常,呼叫就必須處理。
如果是執行時期異常,呼叫者可以處理,也可以不處理。
1.7
throws:(演示檔案未找到異常,除數為0異常)
用在方法宣告後面,跟的是異常類名
可以跟多個異常類名,用,號隔開
表示丟擲異常,由該方法的呼叫者來處理
throws表示出現異常的一種可能,並不一定會發生這些異常
1.8
異常處理:
try…catch…finally

finally:一般用於釋放資源。在資料庫操作或者IO流比較常見。

特點:
被finally控制的語句體一定會執行

    特殊情況:在執行到finally之前jvm退出了(比如System.exit(0))

1.9
finally相關的面試題:
final,finally的區別?
final:最終的意思。可以修飾類,方法,變數。
修飾類,類不能被繼承
修飾方法,方法不能被重寫
修飾變數,變數是常量
finally:
異常處理的一部分。被finally控制的程式碼一定會執行。
特殊情況:在執行到finally之前,jvm退出了。
1.9.1
注意:
A:子類重寫父類方法時,子類的方法必須丟擲相同的異常或父類異常的子類。(父親壞了,兒子不能比父親更壞)
B:如果父類丟擲了多個異常,子類重寫父類時,只能丟擲相同的異常或者是他的子集,子類不能丟擲父類沒有的異常
C:如果被重寫的方法沒有異常丟擲,那麼子類的方法絕對不可以丟擲異常,如果子類方法內有異常發生,那麼子類只能try,不能throws

    上述僅僅針對編譯時期異常
    與執行時期異常無關。

1.9.2
throw和throws的區別?
throws:
用在方法宣告後面,跟的是異常類名
可以跟多個異常類名,用逗號隔開
表示丟擲異常,由該方法的呼叫者來處理
throws表示出現異常的一種可能性,並不一定會發生這些異常

throw:
用在方法體內,跟的是異常物件名
只能丟擲一個異常物件名
表示丟擲異常,由方法體內的語句處理
throw則是丟擲了異常,執行throw則一定丟擲了某種異常?
案例演示:演示編譯時期異常(檔案未找到異常)和執行時期異常(除數為0異常)使用上的區別
throw:
如果throw的是編譯時期異常,在方法宣告上必須用throws進行標記

這裡寫程式碼片

相關文章