1. 程式人生 > >Android SD卡簡單的檔案讀寫操作

Android SD卡簡單的檔案讀寫操作

Android SD卡簡單的檔案讀寫操作

 

最近有這樣的需求,把每次統計到的資料,以txt形式儲存到手機SD卡或是手機記憶體中,遇到一些問題,記錄下來。

 

首先如果要在程式中使用sdcard進行儲存,我們必須要在AndroidManifset.xml檔案進行下面的許可權設定:

 

[

  1.   <!-- SDCard中建立與刪除檔案許可權 -->  
  2.   <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  
  3.  <!-- 向SDCard寫入資料許可權 -->  
  4.  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  


  接著在使用SDcard進行讀寫的時候 會用到Environment類下面的幾個靜態方法  : 

 

    1: getDataDirectory() 獲取到Android中的data資料目錄(sd卡中的data資料夾)
    2:getDownloadCacheDirectory() 獲取到下載的快取目錄(sd卡中的download資料夾)
    3:getExternalStorageDirectory() 獲取到外部儲存的目錄 一般指SDcard(/storage/sdcard0)
    4:getExternalStorageState() 獲取外部設定的當前狀態 一般指SDcard,比較常用的應該是 MEDIA_MOUNTED(SDcard存在並且可以進行讀寫)還有其他的一些狀態,可以在文件中進行查詢。

    5:getRootDirectory()  獲取到Android Root路徑

 

好,以下是具體操作,直接看程式碼:

1,判斷SD卡是否存在

 

 

  1. /** 
  2.  * 判斷SDCard是否存在 [當沒有外掛SD卡時,內建ROM也被識別為存在sd卡] 
  3.  *  
  4.  * @return 
  5.  */  
  6. public static boolean isSdCardExist() {  
  7.     return Environment.getExternalStorageState().equals(  
  8.             Environment.MEDIA_MOUNTED);  
  9. }  


2,獲取SD卡根目錄

 

 

 

  1. /** 
  2.  * 獲取SD卡根目錄路徑 
  3.  *  
  4.  * @return 
  5.  */  
  6. public static String getSdCardPath() {  
  7.     boolean exist = isSdCardExist();  
  8.     String sdpath = "";  
  9.     if (exist) {  
  10.         sdpath = Environment.getExternalStorageDirectory()  
  11.                 .getAbsolutePath();  
  12.     } else {  
  13.         sdpath = "不適用";  
  14.     }  
  15.     return sdpath;  
  16.   
  17. }  


3,獲取預設的檔案存放路徑

 

 

 

  1. /** 
  2.  * 獲取預設的檔案路徑 
  3.  *  
  4.  * @return 
  5.  */  
  6. public static String getDefaultFilePath() {  
  7.     String filepath = "";  
  8.     File file = new File(Environment.getExternalStorageDirectory(),  
  9.             "abc.txt");  
  10.     if (file.exists()) {  
  11.         filepath = file.getAbsolutePath();  
  12.     } else {  
  13.         filepath = "不適用";  
  14.     }  
  15.     return filepath;  
  16. }  


4-1,使用FileInputStream讀取檔案

 

 

 

  1. try {  
  2. le file = new File(Environment.getExternalStorageDirectory(),  
  3. "test.txt");  
  4.     FileInputStream is = new FileInputStream(file);  
  5.     byte[] b = new byte[inputStream.available()];  
  6.     is.read(b);  
  7.     String result = new String(b);  
  8.     System.out.println("讀取成功:"+result);  
  9. } catch (Exception e) {  
  10.     e.printStackTrace();  
  11. }  


4-2,使用BufferReader讀取檔案

 

 

 

  1. try {  
  2.     File file = new File(Environment.getExternalStorageDirectory(),  
  3.             DEFAULT_FILENAME);  
  4.     BufferedReader br = new BufferedReader(new FileReader(file));  
  5.     String readline = "";  
  6.     StringBuffer sb = new StringBuffer();  
  7.     while ((readline = br.readLine()) != null) {  
  8.         System.out.println("readline:" + readline);  
  9.         sb.append(readline);  
  10.     }  
  11.     br.close();  
  12.     System.out.println("讀取成功:" + sb.toString());  
  13. } catch (Exception e) {  
  14.     e.printStackTrace();  
  15. }  

httpConnection讀取流儲存成String資料

 

 

  1. URL url = new URL(getForwardUrl("/queryUserByUNorIP"));  
  2. HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  3. InputStream is = conn.getInputStream();  
  4. BufferedReader br = new BufferedReader(new InputStreamReader(is));  
  5. StringBuilder sb = new StringBuilder();  
  6. String readline = null;  
  7. while ((readline = br.readLine()) != null) {  
  8.     sb.append(readline);  
  9. }  
  10. System.out.println("result"+sb.toString());  

等效於使用ByteArrayOutputStream

 

 

 

  1. InputStream is = conn.getInputStream();  
  2. ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  3. byte[] buffer = new byte[1024];  
  4. int len =-1 ;  
  5. while ((len=is.read(buffer))!=-1) {  
  6.     bos.write(buffer, 0, len);  
  7. }  
  8. is.close();  
  9. bos.close();  
  10. String result = new String(bos.toByteArray());  
  11. System.out.println("result"+result);  

 

 

5-1,使用FileOutputStream寫入檔案

 

 

 

  1. try {  
  2.     File file = new File(Environment.getExternalStorageDirectory(),  
  3.             DEFAULT_FILENAME);  
  4.         FileOutputStream fos = new FileOutputStream(file);  
  5.         String info = "I am a chinanese!";  
  6.            fos.write(info.getBytes());  
  7.            fos.close();  
  8.     System.out.println("寫入成功:");  
  9. } catch (Exception e) {  
  10.     e.printStackTrace();  
  11. }  


5-2,使用BufferedWriter寫入檔案

 

 

 

  1. try {  
  2.     File file = new File(Environment.getExternalStorageDirectory(),  
  3.             DEFAULT_FILENAME);  
  4.     //第二個引數意義是說是否以append方式新增內容  
  5.     BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));  
  6.     String info = " hey, yoo,bitch";  
  7.     bw.write(info);  
  8.     bw.flush();  
  9.     System.out.println("寫入成功");  
  10. } catch (Exception e) {  
  11.     e.printStackTrace();  
  12. }  

 

 

讀取和寫入我們都實現了,貌似很簡單的樣子,但是我們現在想每隔30秒進行一次資料整理,然後把他們寫入到我們制定的txt檔案中,但是我想每次都能在上一次的結尾處開始寫入,這樣在電腦上通過文字開啟時,就能看到每一行的資料了。

這其實要求我們每一次寫入資料時,都要有換行的操作符號,比如:\n,並且IO讀寫能以追加的方式寫入到檔案裡。

剛開始我很笨的想到,每次寫入前,先把檔案讀取出來並且生成一個StringBuffer,然後再append,然後再寫入.....這種方式導致每次都要2次以上的IO操作,讀和寫。其實系統寫入時就給我們自帶了append方式,還是要勤看文件啊!

BufferedWriter

使用BufferedWriter,在構造BufferedWriter時,把第二個引數設為true
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(  
                    new FileOutputStream(file, true)));  
         out.write(conent);  

FileWriter

建構函式中的第二個引數true表示以追加形式寫檔案  
         FileWriter writer = new FileWriter(fileName, true);  
         writer.write(content);  
         writer.close();

// 開啟一個隨機訪問檔案流,按讀寫方式  
RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");  
// 檔案長度,位元組數  
long fileLength = randomFile.length();  
// 將寫檔案指標移到檔案尾。  
randomFile.seek(fileLength);  
randomFile.writeBytes(content);  
randomFile.close(); 

 

 

問題:我在file寫入時,沒一次寫完後,明明都添加了換行符(bw.write("\n")),為什麼在Window的文字文件中看不到換行呢?而在EditPlus或是notepad++中就能看到換行後的效果?

 

 

  1. BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));  
  2. String info = " hey, yoo,bitch";  
  3. bw.write(info);  
  4. bw.write("\n");  
  5. bw.flush();  


如上程式碼所示,可是在windows的文字文件中:

 

但是在諸如notepad++或EditPlus中看到卻是沒問題的:

 

這是為什麼呢?

這是windows與linux系統的編碼模式不同造成的。android系統是linux核心,與windows不同。windows是採用的是DOS編碼方式,所用的換行符是DOS換行符CR/LF,也就是我們俗稱的\r\n,(如果不理解可以去百度一下轉義字元,一般程式設計師會用到這些知識),而linux系統的換行符為UNIX換行符LF,也就是\n,蘋果的MAC系統用的是MAC換行符CR,也就是\r,現在我想你也差不多理解了。你在android手機裡建立的文件肯定用的是UNIX換行符,也就是一個\n,但是這個文件你拿到windows裡用記事本開啟的話,因為windows記事本是DOS換行符\r\n,所以你少了個\r,所以沒法識別成換行,只能給你識別成一個小方塊了,解決辦法很簡單,你可以用EditPlus或者UltraEdit軟體開啟,UltraEdit也能轉換這些編碼模式,轉換成DOS模式就可以了。

 

所以,我們只需要新增:\r\n  

 

 

  1. BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));  
  2. String info = " hey, yoo,bitch";  
  3. bw.write(info);  
  4. bw.write("\r\n");  
  5. bw.flush();