【轉(zhuǎn)】
創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司一直秉承“誠信做人,踏實(shí)做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個(gè)客戶多一個(gè)朋友!專注中小微企業(yè)官網(wǎng)定制,成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站,塑造企業(yè)網(wǎng)絡(luò)形象打造互聯(lián)網(wǎng)企業(yè)效應(yīng)。
首先介紹如何存儲數(shù)據(jù),顯然,要將數(shù)據(jù)從應(yīng)用中輸出到文件中,必須得到一個(gè)輸出流outPutStream,然后往輸出流中寫入數(shù)據(jù),在這里Android自帶了一個(gè)得到應(yīng)用輸出流的方法
FileOutputStream fos =context.openFileOutput(“yuchao.txt”,Context.MODE_PRIVATE); ?(1)
其中第一個(gè)屬性為文件名,第二個(gè)屬性為讀寫模式(有關(guān)讀寫模式的說明下面將詳細(xì)闡述),
然后在文件輸出流fos中便可以寫入數(shù)據(jù)
Fos.write(“Hi,”I’m Chao Yu!”.getBytes());
用完文件輸出流之后記得關(guān)閉
fos.close();
這樣,在/data/data/packageName/file目錄下就生成了一個(gè)文件名為yuchao.txt的文件,文件中的內(nèi)容為” Hi,I’m Chao Yu!”
有關(guān)(1)中讀寫模式其實(shí)就是制定創(chuàng)建文件的權(quán)限以及在讀寫的時(shí)候的方式,Android中提供了以下幾種讀寫模式
Context.MODE_PRIVATE ? ?= ?0
該模式下創(chuàng)建的文件其他應(yīng)用無權(quán)訪問,并且本應(yīng)用將覆蓋原有的內(nèi)容
Context.MODE_APPEND ? ?= ?32768
該模式下創(chuàng)建的文件其他應(yīng)用無權(quán)訪問,并且本應(yīng)用將在原有的內(nèi)容后面追加內(nèi)容
Context.MODE_WORLD_READABLE = ?1
該模式下創(chuàng)建的文件其他應(yīng)用有讀的權(quán)限
Context.MODE_WORLD_WRITEABLE = ?2
該模式下創(chuàng)建的文件其他應(yīng)用有寫的權(quán)限
如果需要將文件設(shè)置為外部應(yīng)用可以讀寫,可將讀寫模式設(shè)置為Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE
一般情況下,各個(gè)應(yīng)用維護(hù)的數(shù)據(jù)都在一個(gè)特定的文件夾中,即上面所提到的/data/data/packageName/file(存在于手機(jī)存儲中),但手機(jī)內(nèi)存畢竟有限,所以有些情況下,我們需要往SD卡中寫入數(shù)據(jù)文件,這其實(shí)和普通的java web 應(yīng)用步驟一樣,都是先創(chuàng)建特針對特定目錄特定文件的輸出流,然后往輸出流中寫數(shù)據(jù),這里要注意一個(gè)方法,就是獲取SD卡根目錄的方法,隨著Android系統(tǒng)不斷升級,SD卡的根目錄隨時(shí)都有可能改變,Android中得到SD卡根目錄的方法是
File sdCardDir = Environment.getExternalStorageDirectory();
然后就可以進(jìn)行下面的步驟
File saveFile = new File(sdCardDir, “yuchao.txt”);
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("Hi,I’m ChaoYu".getBytes());
outStream.close();
值得注意的是,在往SD卡中寫數(shù)據(jù)的時(shí)候,健壯的代碼必須考慮SD卡不存在或者寫保護(hù)的情況,故在寫入之前,先做判斷
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
……
}
接著,我們來學(xué)習(xí)下我們的應(yīng)用程序如何讀取文件中的數(shù)據(jù),其實(shí)就是寫的逆向過程
若要讀取應(yīng)用程序默認(rèn)維護(hù)的文件(即/data/data/packageName/file目錄下的文件),首先得到文件輸入流
FileInputStream istream = this.context.openFileInput(“yuchao.txt”);
然后在內(nèi)存中開辟一段緩沖區(qū)
byte[] buffer = new byte[1024];
然后創(chuàng)建一個(gè)字節(jié)數(shù)組輸出流
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
讀出來的數(shù)據(jù)首先放入緩沖區(qū),滿了之后再寫到字符輸出流中
while((len=istream.read(buffer))!=-1){
ostream.write(buffer, 0, len);
}
最后關(guān)閉輸入流和輸出流
istream.close();
ostream.close();
將得到的內(nèi)容以字符串的形式返回便得到了文件中的內(nèi)容了,這里的流操作較多,故以一張圖片來說明,見圖1
return new String(ostream.toByteArray());
從SD卡中讀取數(shù)據(jù)與上述兩個(gè)步驟類似,故不再贅述,留給讀者自己思考
如在開發(fā)過程中進(jìn)行SD卡地讀寫,切忌忘了加入權(quán)限
uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/
至此,Android系統(tǒng)中有關(guān)文件數(shù)據(jù)的讀寫介紹完畢。
IO流(操作文件內(nèi)容): 字節(jié)流
參考:
AssetManager
assets 文件夾用于存儲應(yīng)用需要的文件,在安裝后可直接從其中讀取使用或者寫入本地存儲中
Android Studio 默認(rèn)不建立該文件夾,可以手動(dòng)新建 : app - src - main - assets
或者,右鍵 main - New - Folder - Assets Folder
AssetManager 對象可以直接訪問該文件夾:
獲取方法:
使用函數(shù) open 可以打開 assets 文件夾中對象,返回一個(gè) InputStream 對象:
open
獲取方法:
讀文件:
1、通過File獲取文件
2、打開輸入流,讀取文件
寫文件:
1、創(chuàng)建文件
2、打開輸出流,寫入文件內(nèi)容
示例:
讀文件:
String?content?=?"";?//文件內(nèi)容字符串
//通過路徑/sdcard/foo.txt打開文件
File?file?=?new?File("/sdcard/foo.txt");
try?{
InputStream?instream?=?new?FileInputStream(file);//讀取輸入流
InputStreamReader?inputreader?=?new?InputStreamReader(instream);//設(shè)置流讀取方式
BufferedReader?buffreader?=?new?BufferedReader(inputreader);
while?((?line?=?buffreader.readLine())?!=?null)?{
content?+=?line?+?"\n";//讀取的文件內(nèi)容
}
}catch(Exception?ex){
}
寫文件:
File?file?=?new?File("/sdcard/foo.txt");//
if(!file.exists())
file.createNewFile();//如果文件不存在,創(chuàng)建foo.txt
try?{
OutputStream?outstream?=?new?FileOutputStream(file);//設(shè)置輸出流
OutputStreamWriter?out?=?new?OutputStreamWriter(outstream);//設(shè)置內(nèi)容輸出方式
out.write("文字內(nèi)容");//輸出內(nèi)容到文件中
out.close();
}?catch?(java.io.IOException?e)?{
e.printStackTrace();
}
!--往sdcard中寫入數(shù)據(jù)的權(quán)限 --uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/uses-permission!--在sdcard中創(chuàng)建/刪除文件的權(quán)限 --uses-permission android:name="android.permission.MOUNT_U
android中的apk必須簽名
這種簽名不是基于權(quán)威證書的,不會決定某個(gè)應(yīng)用允不允許安裝,而是一種自簽名證書。
重要的是,android系統(tǒng)有的權(quán)限是基于簽名的。比如:system等級的權(quán)限有專門對應(yīng)的簽名,簽名不對,權(quán)限也就獲取不到。默認(rèn)生成的APK文件是debug簽名的。
獲取system權(quán)限時(shí)用到的簽名,見:如何使Android應(yīng)用程序獲取系統(tǒng)權(quán)限?;赨serID的進(jìn)程級別的安全機(jī)。這種簽名不是基于權(quán)威證書的,不會決定某個(gè)應(yīng)用允不允許安裝,而是一種自簽名證書。重要的是,android系統(tǒng)有的權(quán)限是基于簽名的。
android10刪除文件后寫文件如下
1.將數(shù)據(jù)存儲到文件中(文件默認(rèn)存儲到data/data/包名/files目錄下)htmlpublic void save(String inputText) {//inputText為傳入的要保存的數(shù)據(jù)FileOutputStream out = null;BufferedWriter writer = null;try {= openFileOutput("data", Context.MODE_APPEND);//"data"為文件名,第二個(gè)參數(shù)為文件操做模式:文件已經(jīng)存在,就往文件里面追加類容,不重新建立文件。
writer = new BufferedWriter(new OutputStreamWriter(out));writer.write(inputText);} catch (IOException e) {e.printStackTrace();} finally {try {if (writer != null) {writer.close();
2.從文件中讀取數(shù)據(jù)android//讀取數(shù)據(jù)= load();if (!TextUtils.isEmpty(inputText1)) {//非空判斷,傳入為null和空字符串時(shí)返回true//將數(shù)據(jù)展現(xiàn)到listview控件 );//android.R.layout.simple_list_item_1android內(nèi)置子布adapter.add(inputText1);ListViewBattery5.setAdapter(adapter)。
分以下幾個(gè)步驟:
首先對manifest注冊SD卡讀寫權(quán)限
AndroidManifest.xml?
?xml?version="1.0"?encoding="utf-8"??
manifest?xmlns:android="
package="com.tes.textsd"?
android:versionCode="1"?
android:versionName="1.0"??
uses-sdk?
android:minSdkVersion="8"?
android:targetSdkVersion="16"?/?
uses-permission?android:name="android.permission.WRITE_EXTERNAL_STORAGE"/?
application?
android:allowBackup="true"?
android:icon="@drawable/ic_launcher"?
android:label="@string/app_name"?
android:theme="@style/AppTheme"??
activity?
android:name="com.tes.textsd.FileOperateActivity"?
android:label="@string/app_name"??
intent-filter?
action?android:name="android.intent.action.MAIN"?/?
category?android:name="android.intent.category.LAUNCHER"?/?
/intent-filter?
/activity?
/application?
/manifest
創(chuàng)建一個(gè)對SD卡中文件讀寫的類
FileHelper.java?
/**?
*?@Title:?FileHelper.java?
*?@Package?com.tes.textsd?
*?@Description:?TODO(用一句話描述該文件做什么)?
*?@author?Alex.Z?
*?@date?2013-2-26?下午5:45:40?
*?@version?V1.0?
*/?
package?com.tes.textsd;?
import?java.io.DataOutputStream;?
import?java.io.File;?
import?java.io.FileOutputStream;?
import?java.io.FileWriter;?
import?java.io.FileInputStream;?
import?java.io.FileNotFoundException;?
import?java.io.IOException;?
import?android.content.Context;?
import?android.os.Environment;?
public?class?FileHelper?{?
private?Context?context;?
/**?SD卡是否存在**/?
private?boolean?hasSD?=?false;?
/**?SD卡的路徑**/?
private?String?SDPATH;?
/**?當(dāng)前程序包的路徑**/?
private?String?FILESPATH;?
public?FileHelper(Context?context)?{?
this.context?=?context;?
hasSD?=?Environment.getExternalStorageState().equals(?
android.os.Environment.MEDIA_MOUNTED);?
SDPATH?=?Environment.getExternalStorageDirectory().getPath();?
FILESPATH?=?this.context.getFilesDir().getPath();?
}?
/**?
*?在SD卡上創(chuàng)建文件?
*?
*?@throws?IOException?
*/?
public?File?createSDFile(String?fileName)?throws?IOException?{?
File?file?=?new?File(SDPATH?+?"http://"?+?fileName);?
if?(!file.exists())?{?
file.createNewFile();?
}?
return?file;?
}?
/**?
*?刪除SD卡上的文件?
*?
*?@param?fileName?
*/?
public?boolean?deleteSDFile(String?fileName)?{?
File?file?=?new?File(SDPATH?+?"http://"?+?fileName);?
if?(file?==?null?||?!file.exists()?||?file.isDirectory())?
return?false;?
return?file.delete();?
}?
/**?
*?寫入內(nèi)容到SD卡中的txt文本中?
*?str為內(nèi)容?
*/?
public?void?writeSDFile(String?str,String?fileName)?
{?
try?{?
FileWriter?fw?=?new?FileWriter(SDPATH?+?"http://"?+?fileName);?
File?f?=?new?File(SDPATH?+?"http://"?+?fileName);?
fw.write(str);?
FileOutputStream?os?=?new?FileOutputStream(f);?
DataOutputStream?out?=?new?DataOutputStream(os);?
out.writeShort(2);?
out.writeUTF("");?
System.out.println(out);?
fw.flush();?
fw.close();?
System.out.println(fw);?
}?catch?(Exception?e)?{?
}?
}?
/**?
*?讀取SD卡中文本文件?
*?
*?@param?fileName?
*?@return?
*/?
public?String?readSDFile(String?fileName)?{?
StringBuffer?sb?=?new?StringBuffer();?
File?file?=?new?File(SDPATH?+?"http://"?+?fileName);?
try?{?
FileInputStream?fis?=?new?FileInputStream(file);?
int?c;?
while?((c?=?fis.read())?!=?-1)?{?
sb.append((char)?c);?
}?
fis.close();?
}?catch?(FileNotFoundException?e)?{?
e.printStackTrace();?
}?catch?(IOException?e)?{?
e.printStackTrace();?
}?
return?sb.toString();?
}?
public?String?getFILESPATH()?{?
return?FILESPATH;?
}?
public?String?getSDPATH()?{?
return?SDPATH;?
}?
public?boolean?hasSD()?{?
return?hasSD;?
}?
}
寫一個(gè)用于檢測讀寫功能的的布局
main.xml?
?xml?version="1.0"?encoding="utf-8"??
LinearLayout?xmlns:android="
android:layout_width="fill_parent"?
android:layout_height="fill_parent"?
android:orientation="vertical"??
TextView?
android:id="@+id/hasSDTextView"?
android:layout_width="fill_parent"?
android:layout_height="wrap_content"?
android:text="hello"?/?
TextView?
android:id="@+id/SDPathTextView"?
android:layout_width="fill_parent"?
android:layout_height="wrap_content"?
android:text="hello"?/?
TextView?
android:id="@+id/FILESpathTextView"?
android:layout_width="fill_parent"?
android:layout_height="wrap_content"?
android:text="hello"?/?
TextView?
android:id="@+id/createFileTextView"?
android:layout_width="fill_parent"?
android:layout_height="wrap_content"?
android:text="false"?/?
TextView?
android:id="@+id/readFileTextView"?
android:layout_width="fill_parent"?
android:layout_height="wrap_content"?
android:text="false"?/?
TextView?
android:id="@+id/deleteFileTextView"?
android:layout_width="fill_parent"?
android:layout_height="wrap_content"?
android:text="false"?/?
/LinearLayout
就是UI的類了
FileOperateActivity.class?
/**?
*?@Title:?FileOperateActivity.java?
*?@Package?com.tes.textsd?
*?@Description:?TODO(用一句話描述該文件做什么)?
*?@author?Alex.Z?
*?@date?2013-2-26?下午5:47:28?
*?@version?V1.0?
*/?
package?com.tes.textsd;?
import?java.io.IOException;?
import?android.app.Activity;?
import?android.os.Bundle;?
import?android.widget.TextView;?
public?class?FileOperateActivity?extends?Activity?{?
private?TextView?hasSDTextView;?
private?TextView?SDPathTextView;?
private?TextView?FILESpathTextView;?
private?TextView?createFileTextView;?
private?TextView?readFileTextView;?
private?TextView?deleteFileTextView;?
private?FileHelper?helper;?
@Override?
public?void?onCreate(Bundle?savedInstanceState)?{?
super.onCreate(savedInstanceState);?
setContentView(R.layout.main);?
hasSDTextView?=?(TextView)?findViewById(R.id.hasSDTextView);?
SDPathTextView?=?(TextView)?findViewById(R.id.SDPathTextView);?
FILESpathTextView?=?(TextView)?findViewById(R.id.FILESpathTextView);?
createFileTextView?=?(TextView)?findViewById(R.id.createFileTextView);?
readFileTextView?=?(TextView)?findViewById(R.id.readFileTextView);?
deleteFileTextView?=?(TextView)?findViewById(R.id.deleteFileTextView);?
helper?=?new?FileHelper(getApplicationContext());?
hasSDTextView.setText("SD卡是否存在:"?+?helper.hasSD());?
SDPathTextView.setText("SD卡路徑:"?+?helper.getSDPATH());?
FILESpathTextView.setText("包路徑:"?+?helper.getFILESPATH());?
try?{?
createFileTextView.setText("創(chuàng)建文件:"?
+?helper.createSDFile("test.txt").getAbsolutePath());?
}?catch?(IOException?e)?{?
e.printStackTrace();?
}?
deleteFileTextView.setText("刪除文件是否成功:"?
+?helper.deleteSDFile("xx.txt"));?
helper.writeSDFile("1213212",?"test.txt");?
readFileTextView.setText("讀取文件:"?+?helper.readSDFile("test.txt"));?
}?
}