詳細講解Android的圖片下載架構UniversialImageLoader之磁碟緩衝的擴充(二),

來源:互聯網
上載者:User

詳細講解Android的圖片下載架構UniversialImageLoader之磁碟緩衝的擴充(二),

       相對於第一篇來講,這裡講的是磁碟緩衝的延續。在這裡我們主要是關注四個類,分別是DiskLruCache、LruDiskCache、StrictLineReader以及工具類Util。

       接下來逐一的對它們進行剖析。廢話不多說。

       首先來看一下DiskLruCache。

       這個類的主要功能是什麼呢?我們先來看一段類的注釋:

      

 /** * A cache that uses a bounded amount of space on a filesystem. Each cache * entry has a string key and a fixed number of values. Each key must match * the regex <strong>[a-z0-9_-]{1,64}</strong>. Values are byte sequences, * accessible as streams or files. Each value must be between {@code 0} and * {@code Integer.MAX_VALUE} bytes in length. * <p>This class is tolerant of some I/O errors. If files are missing from the * filesystem, the corresponding entries will be dropped from the cache. If * an error occurs while writing a cache value, the edit will fail silently. * Callers should handle other problems by catching {@code IOException} and * responding appropriately. */
對英文不感興趣的童鞋別急,下面稍微翻譯一下:

這是基於檔案系統所構建的一個基於有限空間的緩衝。每一個緩衝入口都有一個字串秘鑰與固定的數位序列。每一個秘鑰一定要與Regex<strong>[a-z0-9_-]{1,64}</strong>進行匹配。數值則是一些位元組序列,是可以作為流或者檔案被訪問的。每一個數值在長度上一定是在0與最大的整數之間的。這個緩衝類對部分的I/O操作室容忍的。如果有一些檔案從檔案系統中丟失,相應的緩衝的入口ᐟ會從緩衝中移除。如果在寫入一個緩衝的數值的時候發生了以外的錯誤,

當前的編輯也會默默的撤銷,回調者則會通過捕獲一些I/O異常與核實的回應來處理一些其他的問題。

由於DiskLruCache的代碼量較多,我們還是從一些核心的變數與方法上來講述它。核心變數如下:

static final String JOURNAL_FILE = "journal";static final String JOURNAL_FILE_TEMP = "journal.tmp";static final String JOURNAL_FILE_BACKUP = "journal.bkp";static final String MAGIC = "libcore.io.DiskLruCache";static final String VERSION_1 = "1";static final long ANY_SEQUENCE_NUMBER = -1;static final Pattern LEGAL_KEY_PATTERN = Pattern.compile("[a-z0-9_-]{1,64}");private static final String CLEAN = "CLEAN";private static final String DIRTY = "DIRTY";private static final String REMOVE = "REMOVE";private static final String READ = "READ";private final File directory;private final File journalFile;private final File journalFileTmp;private final File journalFileBackup;private final int appVersion;private long maxSize;private int maxFileCount;private final int valueCount;private long size = 0;private int fileCount = 0;private Writer journalWriter;private final LinkedHashMap<String, Entry> lruEntries =new LinkedHashMap<String, Entry>(0, 0.75f, true);private int redundantOpCount;private long nextSequenceNumber = 0;final ThreadPoolExecutor executorService =new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

上面的變數大致進行歸類,包括:記錄檔的命名,記錄檔的開始5行內容的變數的定義,檔案尺寸與數量的限制以及一個LinkedHashMap來維持一個緩衝隊列,最後還有一個線程池。

接下來大致介紹一下裡面的函數的功能:

1、readJournal  這個函數的功能是1、計算當前的日誌的緩衝的行數、2、計算當前的緩衝的記錄檔中冗餘的行數  3、讀取並且處理緩衝的日誌中的每一行的資料

2、readJournalLine 這個函數的功能是真正的執行每一行日誌的操作   當在日誌中遇到一個關鍵字的時候,從當前的緩衝的度列中查看當前的關鍵字所映射的對象是否存在,如果不存在,以當前的關鍵字建立一個新的對象並且放到當前的緩衝的隊列中。

3、processJournal  計算初始化的尺寸,並且回收緩衝中的一些垃圾。髒的入口將會被認為是前後矛盾的,將會被回收。

4、rebuildJournal 這個函數的功能是建立一個新的刪除大量冗餘資訊的記錄檔,如果當前的記錄檔存在,將會替換掉當前的記錄檔。

5、

public synchronized Snapshot get(String key) throws IOException

這個函數的功能是返回一個命名為key的檔案入口的快照。並且如果當前的數值是返回的,那麼它將會被移動到LRU隊列的頭部。

6、

public synchronized boolean remove(String key) throws IOException

如果當前的檔案實體是存在的並且是可以刪除的,那麼就刪除當前的檔案的實體。當前正在被編輯的檔案實體是不能夠被刪除的。

接下來關注一下這個類中的三個比較重要的內部類,分別是Snapshot、Editor與Entry。

大致介紹一些這三個類的功能。

Snapshot是緩衝的檔案實體的數值的一個快照。Editor是編輯緩衝的檔案實體的數值。Entry是緩衝的檔案實體的資料模型。


接下來我們分下一下LruDiskCache這個類的主要功能。

正如這個類的名稱一樣,這是一個最近最久未使用的磁碟緩衝。這樣這個類的大致的功能我們清楚了。

我們會在這個類中看到這樣一個成員變數

protected DiskLruCache cache;

由此可見當前的類,是DiskLruCache針對磁碟緩衝的介面的一個適配器。不信?我們從下面的方法中可以看出:

1、

@Overridepublic File getDirectory() {return cache.getDirectory();}

擷取當前的緩衝的目錄。

2、

public File get(String imageUri) {DiskLruCache.Snapshot snapshot = null;try {snapshot = cache.get(getKey(imageUri));return snapshot == null ? null : snapshot.getFile(0);} catch (IOException e) {L.e(e);return null;} finally {if (snapshot != null) {snapshot.close();}}}

通過圖片的uri的對象擷取圖片檔案的控制代碼。  是通過DiskLruCache中的快照實現的。


3、

public boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException {DiskLruCache.Editor editor = cache.edit(getKey(imageUri));if (editor == null) {return false;}OutputStream os = new BufferedOutputStream(editor.newOutputStream(0), bufferSize);boolean copied = false;try {copied = IoUtils.copyStream(imageStream, os, listener, bufferSize);} finally {IoUtils.closeSilently(os);if (copied) {editor.commit();} else {editor.abort();}}return copied;}

利用的是DiskLruCache中的檔案編輯類Editor來講當前的檔案輸入資料流寫到產生的檔案中。

其餘的函數也是以此類推。


接下來要講的類StrictLineReader,我們也是可將將其理解為一個協助類,它是專門為讀取緩衝日誌的內容而特別設計的。

主要觀察下面的一個方法:

public String readLine() throws IOException {synchronized (in) {if (buf == null) {throw new IOException("LineReader is closed");}if (pos >= end) {fillBuf();}for (int i = pos; i != end; ++i) {if (buf[i] == LF) {int lineEnd = (i != pos && buf[i - 1] == CR) ? i - 1 : i;String res = new String(buf, pos, lineEnd - pos, charset.name());pos = i + 1;return res;}}ByteArrayOutputStream out = new ByteArrayOutputStream(end - pos + 80) {@Overridepublic String toString() {int length = (count > 0 && buf[count - 1] == CR) ? count - 1 : count;try {return new String(buf, 0, length, charset.name());} catch (UnsupportedEncodingException e) {throw new AssertionError(e); // Since we control the charset this will never happen.}}};while (true) {out.write(buf, pos, end - pos);// Mark unterminated line in case fillBuf throws EOFException or IOException.end = -1;fillBuf();for (int i = pos; i != end; ++i) {if (buf[i] == LF) {if (i != pos) {out.write(buf, pos, i - pos);}pos = i + 1;return out.toString();}}}}}


在最後一個類Util中,主要是封裝了三個方法,

1、readFully  從Reader中讀取內容,並且拼接成為一個完整的字串

2、deleteContents 迭代刪除檔案的目錄的內容

3、closeQuietly 靜默關閉檔案流


Ok,關於磁碟儲存的擴充就講到這裡,希望對各位童鞋有所協助。












聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.