Android SD卡簡單的檔案讀寫操作
Android SD卡簡單的檔案讀寫操作
最近有這樣的需求,把每次統計到的資料,以txt形式儲存到手機SD卡或是手機記憶體中,遇到一些問題,記錄下來。
首先如果要在程式中使用sdcard進行儲存,我們必須要在AndroidManifset.xml檔案進行下面的許可權設定:
[
- <!-- SDCard中建立與刪除檔案許可權 -->
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
- <!-- 向SDCard寫入資料許可權 -->
- <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卡是否存在
- /**
- * 判斷SDCard是否存在 [當沒有外掛SD卡時,內建ROM也被識別為存在sd卡]
- *
- * @return
- */
- public static boolean isSdCardExist() {
- return Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED);
- }
2,獲取SD卡根目錄
- /**
- * 獲取SD卡根目錄路徑
- *
- * @return
- */
- public static String getSdCardPath() {
- boolean exist = isSdCardExist();
- String sdpath = "";
- if (exist) {
- sdpath = Environment.getExternalStorageDirectory()
- .getAbsolutePath();
- } else {
- sdpath = "不適用";
- }
- return sdpath;
- }
3,獲取預設的檔案存放路徑
- /**
- * 獲取預設的檔案路徑
- *
- * @return
- */
- public static String getDefaultFilePath() {
- String filepath = "";
- File file = new File(Environment.getExternalStorageDirectory(),
- "abc.txt");
- if (file.exists()) {
- filepath = file.getAbsolutePath();
- } else {
- filepath = "不適用";
- }
- return filepath;
- }
4-1,使用FileInputStream讀取檔案
- try {
- le file = new File(Environment.getExternalStorageDirectory(),
- "test.txt");
- FileInputStream is = new FileInputStream(file);
- byte[] b = new byte[inputStream.available()];
- is.read(b);
- String result = new String(b);
- System.out.println("讀取成功:"+result);
- } catch (Exception e) {
- e.printStackTrace();
- }
4-2,使用BufferReader讀取檔案
- try {
- File file = new File(Environment.getExternalStorageDirectory(),
- DEFAULT_FILENAME);
- BufferedReader br = new BufferedReader(new FileReader(file));
- String readline = "";
- StringBuffer sb = new StringBuffer();
- while ((readline = br.readLine()) != null) {
- System.out.println("readline:" + readline);
- sb.append(readline);
- }
- br.close();
- System.out.println("讀取成功:" + sb.toString());
- } catch (Exception e) {
- e.printStackTrace();
- }
httpConnection讀取流儲存成String資料
- URL url = new URL(getForwardUrl("/queryUserByUNorIP"));
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- InputStream is = conn.getInputStream();
- BufferedReader br = new BufferedReader(new InputStreamReader(is));
- StringBuilder sb = new StringBuilder();
- String readline = null;
- while ((readline = br.readLine()) != null) {
- sb.append(readline);
- }
- System.out.println("result"+sb.toString());
等效於使用ByteArrayOutputStream
- InputStream is = conn.getInputStream();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len =-1 ;
- while ((len=is.read(buffer))!=-1) {
- bos.write(buffer, 0, len);
- }
- is.close();
- bos.close();
- String result = new String(bos.toByteArray());
- System.out.println("result"+result);
5-1,使用FileOutputStream寫入檔案
- try {
- File file = new File(Environment.getExternalStorageDirectory(),
- DEFAULT_FILENAME);
- FileOutputStream fos = new FileOutputStream(file);
- String info = "I am a chinanese!";
- fos.write(info.getBytes());
- fos.close();
- System.out.println("寫入成功:");
- } catch (Exception e) {
- e.printStackTrace();
- }
5-2,使用BufferedWriter寫入檔案
- try {
- File file = new File(Environment.getExternalStorageDirectory(),
- DEFAULT_FILENAME);
- //第二個引數意義是說是否以append方式新增內容
- BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));
- String info = " hey, yoo,bitch";
- bw.write(info);
- bw.flush();
- System.out.println("寫入成功");
- } catch (Exception e) {
- e.printStackTrace();
- }
讀取和寫入我們都實現了,貌似很簡單的樣子,但是我們現在想每隔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++中就能看到換行後的效果?
- BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));
- String info = " hey, yoo,bitch";
- bw.write(info);
- bw.write("\n");
- 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
- BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));
- String info = " hey, yoo,bitch";
- bw.write(info);
- bw.write("\r\n");
- bw.flush();