Java 基礎(十一)File 操作及自定義MySharedPreferences

diamond_lin發表於2019-03-01

File 概述

我們先來看看 File 類的定義

File :檔案和目錄路徑名的抽象表示形式。

嗯~ File 可以用來表示一個檔案及其路徑等相關資訊。
資料夾是一個特殊的檔案。

好吧,不瞎扯了,大家都知道 File 是用來表示檔案就行了,我們來看看 API

方法名 方法描述
canExecute() 測試應用程式是否可執行此抽象路徑名錶示的檔案
canRead() 測試應用程式是否可讀取此抽象路徑名錶示的檔案
canWrite() 測試應用程式是否可修改此抽象路徑名錶示的檔案
createNewFile() 當且僅當該檔案不存在時,建立一個新的空檔案
delete() 刪除此抽象路徑名錶示的檔案或目錄
deleteOnExit() 在虛擬機器終止時,請求刪除此抽象路徑名錶示的檔案或目錄
exists() 測試此抽象路徑名錶示的檔案或目錄是否存在
getAbsoluteFile() 返回此抽象路徑名的絕對路徑名形式
getAbsolutePath() 返回此抽象路徑名的絕對路徑名字串
getCanonicalFile() 返回此抽象路徑名的規範形式
getCanonicalPath() 返回此抽象路徑名的規範路徑名字串
getFreeSpace() 返回此抽象路徑名指定的分割槽中未分配的位元組數
getName() 返回由此抽象路徑名錶示的檔案或目錄的名稱
getParent() 返回此抽象路徑名父目錄的路徑名字串;如果此路徑名沒有指定父目錄,則返回 null
getParentFile() 返回此抽象路徑名父目錄的抽象路徑名;如果此路徑名沒有指定父目錄,則返回 null
getPath() 將此抽象路徑名轉換為一個路徑名字串
getTotalSpace() 返回此抽象路徑名指定的分割槽大小
getUsableSpace() 返回此抽象路徑名指定的分割槽上可用於此虛擬機器的位元組數
isAbsolute() 測試此抽象路徑名是否為絕對路徑名
isDirectory() 測試此抽象路徑名錶示的檔案是否是一個目錄
isFile() 測試此抽象路徑名錶示的檔案是否是一個標準檔案
isHidden() 測試此抽象路徑名指定的檔案是否是一個隱藏檔案
lastModified() 返回此抽象路徑名錶示的檔案最後一次被修改的時間
length() 返回由此抽象路徑名錶示的檔案的長度
list() 返回一個字串陣列,這些字串指定此抽象路徑名錶示的目錄中的檔案和目錄
list(FilenameFilter filter) 返回一個字串陣列,這些字串指定此抽象路徑名錶示的目錄中滿足指定過濾器的檔案和目錄
listFiles() 返回一個抽象路徑名陣列,這些路徑名錶示此抽象路徑名錶示的目錄中的檔案
listFiles(FilenameFilter filter) 返回抽象路徑名陣列,這些路徑名錶示此抽象路徑名錶示的目錄中滿足指定過濾器的檔案和目錄
listRoots() 列出可用的檔案系統根
mkdir() 建立此抽象路徑名指定的目錄
mkdirs() 建立此抽象路徑名指定的目錄,包括所有必需但不存在的父目錄
renameTo() 重新命名此抽象路徑名錶示的檔案
setExecutable(boolean executable) 設定此抽象路徑名所有者執行許可權的一個便捷方法
setLastModified(long time) 設定此抽象路徑名指定的檔案或目錄的最後一次修改時間
setReadable(boolean readable) 設定此抽象路徑名所有者讀許可權的一個便捷方法
setReadOnly() 標記此抽象路徑名指定的檔案或目錄,從而只能對其進行讀操作
setWritable(boolean writable) 設定此抽象路徑名所有者寫許可權的一個便捷方法
toURI() 構造一個表示此抽象路徑名的 file: URI
toURL() 過時方法,建議使用 file.toURI().toRUL()

File 練習:列出一個資料夾下所有檔名

需求,列印檔案裡面的所有檔名
思考:資料夾裡面所有檔案,判斷如果是檔案就執行列印,如果是資料夾重複上面操作

剛剛我們思考的這種解決問題思路可以用“遞迴演算法”來實現,我們來簡單瞭解一下上面叫遞迴演算法吧。

遞迴

程式呼叫自身的程式設計技巧稱為遞迴( recursion)。遞迴做為一種演算法在程式設計語言中廣泛應用。 一個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把一個大型複雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大地減少了程式的程式碼量。遞迴的能力在於用有限的語句來定義物件的無限集合。一般來說,遞迴需要有邊界條件、遞迴前進段和遞迴返回段。當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回。

定義

遞迴,就是在執行的過程中呼叫自己

構成遞迴需具備的條件

  • 子問題必須與原始問題為同樣的事,且更為簡單;
  • 不能無限制地呼叫本身,必須有個出口

遞迴演算法一般用於解決以下三類問題:

  • 資料的定義是按遞迴定義的
  • 問題解法按遞迴演算法實現
  • 資料的結構形式是按遞迴定義的(如連結串列、二叉樹、廣義表等)

遞迴的缺點:

遞迴演算法解題相對常用的演算法如普通迴圈等,執行效率較低。因此,應儘量避免使用遞迴,除非沒有更好的演算法或某種特定情況,遞迴更為合適的時候。在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存,遞迴次數過多容易造成棧溢位等。

遞迴的程式碼實現

private static void showDir(File dir) {
    System.out.println("目錄:" + dir);
    File[] files = dir.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            showDir(file);
        } else {
            // 列出根目錄
            System.out.println("files" + file);
        }
    }
}複製程式碼

Properties

額,這是一個我之前沒有接觸過的類,繼承自 HashTable,也就是說它具有 map 集合的特點,而且鍵值對都是字串。

它有什麼特點?為什麼突然在這裡又講集合。。。。

我們來看看 JDK 的描述~

Properties 類表示了一個持久的屬性集,Properties 可儲存在流中或從流中載入.
因為 Properties 繼承於 Hashtable,所以可對 Properties 物件應用 put 和 putAll 方法。但不建議使用這兩個方法,因為它們允許呼叫者插入其鍵或值不是 String 的項。

我們可以從中讀取到幾個重要的資訊。map 集合、字串鍵值對、持久的屬性集。
好了,我就不賣關子了,這玩意可以用來設定配置檔案。

類似於 SharedPreferences,我們可以自己用Properties 來實現MySharedPreferences呀。

我這裡手擼了一個 MySharedPreference,沒有經過測試的,大家湊合著看一下,哈哈?

public class MySharedPreferences {
    private static MySharedPreferences mInstance;
    private final String mPath;

    public static MySharedPreferences getInstance() {
        if (mInstance == null) {
            synchronized (MySharedPreferences.class) {
                if (mInstance == null) {
                    mInstance = new MySharedPreferences();
                }
            }
        }
        return mInstance;
    }

    private MySharedPreferences() {
        mPath = Environment.getExternalStorageDirectory().getPath() + "SP.txt";
        File file = new File(mPath);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void putValue(String key, String value) {
        try {
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(mPath, true));
            BufferedReader bufferedReader = new BufferedReader(new FileReader(mPath));
            Properties properties = new Properties();
            properties.load(bufferedReader);
            properties.setProperty(key, value);
            properties.store(bufferedWriter, "");
            bufferedWriter.flush();
            bufferedReader.close();
            bufferedWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public String getValue(String key) {
        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader(mPath));
            Properties properties = new Properties();
            properties.load(bufferedReader);

            bufferedReader.close();
            return properties.getProperty(key);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}複製程式碼

反正就是醬紫玩的咯,有興趣的小夥伴可以幫我測試一下 MySharedPreference,記得在 Manifest 檔案裡面申請讀寫許可權哦。我覺得是不需要申請許可權的,懶得去測試了,小夥伴們可以根據自己對 android 的理解,告訴我這需不需要許可權。至於效能問題,讀寫 SP 應該是一件低頻率的事情,所以讀寫流在需要的時候建立,不需要的時候關閉。

IO 流及檔案操作的學習就到這裡吧~~
NIO 的併發類的操作等以後學併發的時候再一次性掃盲。

相關文章