天天看點

Android存儲-檔案存儲資料(二)

前言

檔案存儲是Android中最基本的一種資料存儲方式。Android的檔案存儲與Java的檔案存儲類似,都是通過I/O流的形式将資料内容原封不動的存儲到文檔中。因為他比較适合存儲一些簡單的文本資料或二進制資料,如果你希望使用檔案存儲的方式來儲存一些較為複雜的的文本資料,就需要定義一套自己的格式規範,這樣可以友善之後将資料從檔案中重新取出來。

Android中的檔案存儲分為内部存儲和外部存儲;

内部存儲位址:data/data//files/ 目錄

外部存儲位址:檔案存儲到一些外部裝置上(通常位于storage/根目錄下的内外置存儲卡内,不同廠商生産的手機路徑可能不同)。

内外部目錄

在使用檔案存儲前,我們先簡單了解一下内外部目錄擷取方式,這個對于檔案存儲非常重要;對于你将檔案存儲外部位置還是内部依據你所給的路徑決定的,而這裡的路徑擷取方式通過系統方法拿到的。

内部存儲檔案讀寫

Context類中提供了一個openFileOutput()方法和openFileInput(), 分比用于将資料存儲到内部存儲位置和從内部存儲位置擷取資料;存儲路徑為:data/data/包名/file。檔案的存取用到了FileOutputStream和FileInputStream檔案流處理,如果對于這兩個流處理不是很清楚的,可以移駕《使用FileInputStream讀取本地檔案》、《Java輸出流FileOutputStream使用詳解》了解一下。

1、存儲方法openFileOutput()介紹

/**
     * Open a private file associated with this Context's application package
     * for writing. Creates the file if it doesn't already exist.
     * <p>
     * No additional permissions are required for the calling app to read or
     * write the returned file.
     *
     * @param name The name of the file to open; can not contain path
     *            separators.
     * @param mode Operating mode.
     * @return The resulting {@link FileOutputStream}.
     * @see #MODE_APPEND
     * @see #MODE_PRIVATE
     * @see #openFileInput
     * @see #fileList
     * @see #deleteFile
     * @see java.io.FileOutputStream#FileOutputStream(String)
     */
	public abstract FileOutputStream openFileOutput(String name, @FileMode int mode)
	        throws FileNotFoundException;

           

該方法主要有兩個參數,

第一個參數:

該參數就是建立檔案的檔案名。注意不能包含”/”斜杠符号,是以這裡指定的檔案名可以不包含路徑。檔案會 預設存儲到data/data/包名/files目錄下。

第二個參數:

是檔案的操作模式,分别為, MODE_PRIVATE、MODE_APPEND、Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE:

操作模式 解釋說明
Context.MODE_PRIVATE 為預設操作模式,代表該檔案是私有資料,隻能被應用本身通路,在該模式下,寫入的内容會覆寫原檔案的内容,如果想把新寫入的内容追加到原檔案中。可以使用Context.MODE_APPEND
Context.MODE_APPEND 模式會檢查檔案是否存在,存在就往檔案追加内容,否則就建立新檔案。
Context.MODE_WORLD_READABLE 表示目前檔案可以被其他應用讀取;
Context.MODE_WORLD_WRITEABLE 表示目前檔案可以被其他應用寫入。

EXP:

method 1:(寫入byte資料類型)
	String saveInfo = "string";
	//用MODE_PRIVAT模式,建立一個test.txt檔案
	FileOutputStream fileOutput = openFileOutput("test.txt", MODE_PRIVATE);
	fileOutput.write(saveInfo.getBytes());//将我們寫入的字元串變成字元數組
	fileOutput.flush();//重新整理流
    fileOutput.close();//關閉流
    

	method 2:(寫入字元或字元串資料類型)
	String saveInfo = "string";
	FileOutputStream fileOutput = openFileOutput("test.txt", MODE_PRIVATE);
	OutputStreamWriter writerOutput = new OutputStreamWriter(fileOutput);
	BufferedWriter writer = new BufferedWriter(writerOutput );
	writer.write(saveInfo);
	writer.flush();//重新整理流
	writer.close();//關閉流

           

2、取方法openFileInput()介紹

/**
     * Open a private file associated with this Context's application package
     * for reading.
     *
     * @param name The name of the file to open; can not contain path
     *             separators.
     *
     * @return The resulting {@link FileInputStream}.
     *
     * @see #openFileOutput
     * @see #fileList
     * @see #deleteFile
     * @see java.io.FileInputStream#FileInputStream(String)
     */
	public abstract FileInputStream openFileInput(String name)
        throws FileNotFoundException;

           

該方法隻有已個參數,

參數:

這個方法隻有一個參數,就是要打開的檔案名,這個檔案名也不能包含“/”斜杠符号。

EXP:

method 1:(擷取byte資料類型)
	String saveInfo = "string";
	FileInputStream fileInput = openFileInput("test.txt");
	int len = 0;
	//每次讀取1024個byte的資料
    byte[] bytes = new byte[1024];
    while ((len = fileInput.read(bytes)) != -1) {
        sb.append(new String(bytes, 0, len));
    }
	fileInput .flush();//重新整理流
    fileInput .close();//關閉流
    

	method 2:(擷取字元或字元串資料類型)
	String saveInfo = "string";
	FileInputStream fileInput = openFileInput("test.txt", MODE_PRIVATE);
	InputStreamReader readInput = new InputStreamReader(fileInput);
	BufferedReader read = new BufferedReader(readInput);
	String line = "";
    StringBuilder result  = new StringBuilder();
    while ((line = reader.readLine()) != null) {
        result.append(line);
    }
	fileInput.flush();//重新整理流
	fileInput.close();//關閉流

           

外部存儲檔案讀寫

所有的Android裝置都支援儲存檔案到外部存儲,外部存儲可能是可移除的存儲媒體(例如SD卡)或者手機内部媒體,儲存到外部存儲的檔案是全局可讀取檔案,使用者可以修改這些檔案。使用外部存儲幾大因數(純粹個人見解,有不同見解的可以留言探讨及更改):

a、減少内部存儲壓力;
	b、将檔案或資料與其他程序共享;
	c、應用産生的檔案在應用解除安裝後仍需保留。 
           

注意:外部存儲分為公共目錄和私有目錄,外部存儲是可以全局通路的,但需要申請權限:

Android4.4前通路私有目錄和公共目錄都需要申請 WRITE_EXTERNAL_STORAGE 權限
	Android4.4後通路私有目錄不需要申請權限,但公共目錄是需要申請 WRITE_EXTERNAL_STORAGE 權限
           

外部檔案的讀寫操作同樣也用到了I/O流操作,FileOutputStream和FileInputStream檔案流處理,如果對于這兩個流處理不是很清楚的,可以移駕《使用FileInputStream讀取本地檔案》、《Java輸出流FileOutputStream使用詳解》了解一下。

1、存儲方法介紹

這裡簡單講述一下FileOutputStream流幾種建立方式:

第一種:建立FileOutputStream流以寫入資料到指定路徑所代表的檔案,同時建立一個新的FileDescriptor對象來表示與該檔案的關聯(源碼中會new一個該對象);

第二種:建立FileOutputStream流以寫入資料到File對象表示的檔案。 如果第二個參數為true,則位元組将寫入檔案的末尾而不是開頭;如果第二個參數為false,則寫入的内容會覆寫原檔案的内容。 建立一個新的FileDescriptor對象來表示此檔案連接配接。其抛異常的規則與第一個構造函數一緻;

第三種:建立FileOutputStream流以寫入資料到指定路徑所代表的檔案,同時建立一個新的FileDescriptor對象來表示與該檔案的關聯(源碼中會new一個該對象)

第四種:建立FileOutputStream流以寫入資料到指定路徑所代表的檔案,同時建立一個新的FileDescriptor對象來表示與該檔案的關聯(源碼中會new一個該對象), 如果第二個參數為true,則位元組将寫入檔案的末尾而不是開頭,同樣如果第二個參數為false,則寫入的内容會覆寫原檔案的内容

雖然FileOutputStream有四種構造方法,但是究其本質發現都是調用了FileOutputStream(File file,boolean append)這個構造方法,是以後續使用FileOutputStream流時,直接使用該構造方法即可。

EXP:

method 1:(寫入byte資料類型)
	String saveInfo = "string";
	//建立一個test.txt檔案,且使用覆寫方式
	File fileName = new File(Environment.getExternalStoragePublicDirectory(directory), "test.txt");
	FileOutputStream fileOutput = new FileOutputStream(fileName, false);
	fileOutput.write(saveInfo.getBytes());//将我們寫入的字元串變成字元數組
	fileOutput.flush();//重新整理流
    fileOutput.close();//關閉流
    

	method 2:(寫入字元或字元串資料類型)
	String saveInfo = "string";
	File fileName = new File(Environment.getExternalStoragePublicDirectory(directory), "test.txt");
	FileOutputStream fileOutput =  new FileOutputStream(fileName, false);
	OutputStreamWriter writerOutput = new OutputStreamWriter(fileOutput);
	BufferedWriter writer = new BufferedWriter(writerOutput );
	writer.write(saveInfo);
	writer.flush();//重新整理流
	writer.close();//關閉流

           

2、取方法介紹

這裡簡單講述一下FileInputStream流兩種種建立方式:

第一種:通過打開與File類對象代表的實際檔案的連結來建立FileInputStream流對象;

第二種:通過指定的字元串參數來建立File類對象,而後再與File對象所代表的實際路徑建立連結建立FileInputStream流對象

雖然FileOutputStream有四種構造方法,但是究其本質發現都是調用了FileOutputStream(File file,boolean append)這個構造方法,是以後續使用FileOutputStream流時,直接使用該構造方法即可。

EXP:

method 1:(擷取byte資料類型)
	String saveInfo = "string";
	File fileName = new File(Environment.getExternalStoragePublicDirectory(directory), "test.txt");
	FileInputStream fileInput = new FileInputStream(fileName);
	int len = 0;
	//每次讀取1024個byte的資料
    byte[] bytes = new byte[1024];
    while ((len = fileInput.read(bytes)) != -1) {
        sb.append(new String(bytes, 0, len));
    }
	fileInput .flush();//重新整理流
    fileInput .close();//關閉流
    

	method 2:(擷取字元或字元串資料類型)
	String saveInfo = "string";
	File fileName = new File(Environment.getExternalStoragePublicDirectory(directory), "test.txt");
	FileInputStream fileInput = new FileInputStream(fileName);
	InputStreamReader readInput = new InputStreamReader(fileInput);
	BufferedReader read = new BufferedReader(readInput);
	String line = "";
    StringBuilder result  = new StringBuilder();
    while ((line = reader.readLine()) != null) {
        result.append(line);
    }
	fileInput.flush();//重新整理流
	fileInput.close();//關閉流

           

備注

其實不管是内部還是外部存儲,存儲的流程方式基本一緻,唯一不一樣的是對于I/O流FileInputStream和FileOutputStream對象的建立方式不一樣。這裡補充一句,如果對于檔案的權限要求不是很高,建議盡量将檔案資料存儲在外部儲存設備中。

繼續閱讀