Android中文件讀寫操作

? ? ? ? Android開發(fā)中,離不開對文件的操作。本文首先介紹了使用java對文件進行基本的讀寫操作,而后介紹了Android中讀取Assets與raw文件夾中的數(shù)據(jù),最后介紹了Android中讀寫內(nèi)部存儲與外部存儲。

詳細(xì)代碼:讀取Assets與raw文件夾中的數(shù)據(jù)? ??讀寫內(nèi)部存儲與外部存儲

一、文件的基本操作

java中file類的定義:An abstract representation of file and directory pathnames.

創(chuàng)建文件時,先實例化file類,再調(diào)用createNewFile方法

傳入文件路徑可以實例化file對象

Filefile=newFile(FileUtil.FILE_NAME);

通過file.exists()可以判斷文件是否存在,存在返回true

//創(chuàng)建文件

file.createNewFile();

可以獲取文件的各種屬性

"文件名為:"+file.getName()"文件的絕對路徑為"+file.getAbsolutePath()

//文件存放在工程根目錄下,相對路徑只有文件名

"文件的相對路徑為"+file.getPath();

//文件大小,單位bytes,"文件大小為:"+file.length()+”字節(jié)"

"文件是否可讀"+file.canRead()"文件是否可寫"+file.canWrite()"文件是否隱藏"+file.isHidden()

文件重命名,調(diào)用renameTo()方法,需要傳入File類作為參數(shù)

Filefile=newFile(FileUtil.FILE_NAME);

FilenewFile=newFile("AnotherFile.txt");

file.renameTo(newFile);

文件重命名只針對文件本身,重命名后File對象不變,調(diào)用getName()會獲得原值

刪除文件,當(dāng)文件存在時,調(diào)用delete()方法刪除文件

Filefile=newFile(FileUtil.FILE_NAME);

if(file.exists()){file.delete();}

創(chuàng)建文件夾,同樣先實例化file類,然后調(diào)用mkDir或mkDirs方法進行文件夾的創(chuàng)建

//文件夾,創(chuàng)建多級目錄時,不能使用"/"作為分隔符,會因為操作系統(tǒng)的不同而出現(xiàn)異常

//需要使用File.separator(File類中默認(rèn)的分隔符)

publicstaticfinalStringFOLDER_NAME="NewFolder2"+File.separator+"SubFolder2”;

//當(dāng)使用file.mkdir時,如果有任意一級的文件夾不存在時都不會完成創(chuàng)建,file.mkdir();

//使用mkdirs創(chuàng)建文件夾時,有文件夾時,創(chuàng)建下一級文件,否則先創(chuàng)建它本身,再創(chuàng)建下一級文件夾

file.mkdirs();創(chuàng)建時盡量使用mkDirs

刪除文件夾,調(diào)用file.delete()方法

二、讀取assets中的文件數(shù)據(jù)

assets目錄下的文件在打包后會原封不動的保存在apk包中,不會被編譯成二進制

用于儲存較小的文件,可以有目錄結(jié)構(gòu),也就是assets目錄下可以再建立文件夾

assets文件夾下的文件不會被映射到R.java中,訪問的時候需要AssetManager類,即不可使用R.id.fileName進行訪問

創(chuàng)建assets文件夾

在項目結(jié)構(gòu)管理區(qū),選擇project視圖,在app/src/main文件夾下,新建assets文件夾

在項目底部根目錄下的xxx.iml文件中進行配置(xxx為項目工程名)

在configuration 標(biāo)簽下,添加option子標(biāo)簽

通過getResource()或AssetsManager的getAssets()方法獲取字節(jié)流,而后通過文件的一般讀取方式進行讀取。

//通過getAssets獲取InputStream獲取字節(jié)流

InputStream is = getResources().getAssets().open("info.txt");

//將字節(jié)流轉(zhuǎn)換為字符流

InputStreamReader isr =newInputStreamReader(is,"UTF-8");

//創(chuàng)建帶緩沖區(qū)的字符流

BufferedReader bfr =newBufferedReader(isr);

//逐行循環(huán)讀取文件

String in ="";

while((in = bfr.readLine()) !=null){

Log.i(TAG,in);

}

三、讀取raw文件夾中的文件數(shù)據(jù)

assets目錄下的文件在打包后會原封不動的保存在apk包中,不會被編譯成二進制

res/raw中的文件會被映射到R.java文件中,訪問的時候直接使用資源ID即R.id.filename;

創(chuàng)建raw目錄,在res目錄下創(chuàng)建raw目錄,將文件儲存在目錄中

通過getResource.openRawResource()將文件讀取為字節(jié)流,由于文件被影射到R.java文件中,所以參數(shù)可以直接使用R.raw.info,而后按照正常的文件讀寫方式讀寫

InputStream is = getResources().openRawResource(R.raw.info);

InputStreamReader isr =newInputStreamReader(is);

BufferedReader bfr =newBufferedReader(isr);

String in ="";

try{

while((in = bfr.readLine()) !=null){

Log.i(TAG,in);

}

四、讀取內(nèi)部(internal storage)儲存的文件數(shù)據(jù)

程序運行后,在當(dāng)前應(yīng)用下的data->data->應(yīng)用目錄下的儲存空間為文件內(nèi)部儲存空間包含cache和code_cache,只對當(dāng)前應(yīng)用可見。使用OpenFileOutput(filename,寫入模式)方法,可以在應(yīng)用內(nèi)部儲存中自動創(chuàng)建files文件夾,在files文件夾中,創(chuàng)建相應(yīng)文件名的文件。

讀取數(shù)據(jù):程序從輸入流讀取數(shù)據(jù),數(shù)據(jù)源為鍵盤,網(wǎng)絡(luò),文件等。

寫入數(shù)據(jù):程序向輸出流寫入數(shù)據(jù),將程序中的數(shù)據(jù)輸出到顯示器,文件,網(wǎng)絡(luò)

寫入數(shù)據(jù):調(diào)用OpenFileOutput(filename,寫入模式)方法,得到FileOutputStream,包裝成OutputStreamWriter,然后調(diào)用write方法進行寫入,沖刷緩沖區(qū),關(guān)閉流

//文件輸出流,第二個參數(shù)為寫入模式,使用openFileOutPut()方法輸出的文件在

//應(yīng)用程序內(nèi)部儲存空間

FileOutputStream fos = openFileOutput(flieName,Context.MODE_PRIVATE);

//將文件輸出流進一步包裝,變?yōu)榭蓪懭胱址腛utPutStreamWriter

OutputStreamWriter osw =newOutputStreamWriter(fos,"UTF-8");

osw.write(et.getText().toString());

//執(zhí)行flush操作,將緩沖區(qū)的數(shù)據(jù)全部輸出

osw.flush();

fos.flush();

//關(guān)閉流,后打開的流先關(guān)閉

osw.close();

fos.close();

Toast.makeText(MainActivity.this,"寫入完成",Toast.LENGTH_SHORT).show();

讀取數(shù)據(jù):調(diào)用OpenFileInput(filename)方法,得到FileInputStream,包裝成InputStreamReader,創(chuàng)建字符數(shù)組,然后調(diào)用read方法進行讀取,沒有沖刷緩沖區(qū)。記得關(guān)閉流,可將字符數(shù)組轉(zhuǎn)換為 String

//openFileInput()只有一個參數(shù),即需要讀取的文件名

FileInputStream fis = openFileInput(flieName);

//包裝成為InputStreamReader,可調(diào)用read方法

InputStreamReader isr =newInputStreamReader(fis,"UTF-8");

//創(chuàng)建字符數(shù)組,通過fis.available()獲取字符流中可用字符的長度

charinput[] =new char[fis.available()];

//將字符流讀入字符數(shù)組

isr.read(input);

isr.close();

fis.close();

//將字符數(shù)組轉(zhuǎn)為String

String text =newString(input);

//將string設(shè)置為TextView的內(nèi)容

tv.setText(text);

五、讀取外部儲存(external storage)的文件數(shù)據(jù)

外部儲存類似 sd card,一些設(shè)備將"internal" 與 "external" 都做成了不可卸載的內(nèi)置存儲,雖然如此,但是這一整塊還是從邏輯上有被劃分為"internal"與”external”.

Internal storage:

總是可用的

這里的文件默認(rèn)只能被我們的app所訪問。

當(dāng)用戶卸載app的時候,系統(tǒng)會把internal內(nèi)該app相關(guān)的文件都清除干凈。

Internal是我們在想確保不被用戶與其他app所訪問的最佳存儲區(qū)域。

External storage:

并不總是可用的,因為用戶有時會通過USB存儲模式掛載外部存儲器,當(dāng)取下掛載的這部分后,就無法對其進行訪問了。

是大家都可以訪問的,因此保存在這里的文件可能被其他程序訪問。

當(dāng)用戶卸載我們的app時,系統(tǒng)僅僅會刪除external根目錄(getExternalFilesDir())下的相關(guān)文件。

External是在不需要嚴(yán)格的訪問權(quán)限并且希望這些文件能夠被其他app所共享或者是允許用戶通過電腦訪問時的最佳存儲區(qū)域。盡管app是默認(rèn)被安裝到internal storage的,我們還是可以通過在程序的manifest文件中聲明android:installLocation屬性來指定程序安裝到external storage。

獲取external storage權(quán)限:寫入權(quán)限需要在Manifest文件中添加

讀取權(quán)限默認(rèn)目前默認(rèn)擁有,為確保準(zhǔn)確可以聲明

當(dāng)聲明擁有寫入外部儲存權(quán)限時,自動擁有讀取外部儲存的權(quán)限

使用Environment.getExternalStorageDirectory()獲取系統(tǒng)SD卡路徑

當(dāng)最小sdk小于23時,雖然在manifest文件中聲明了權(quán)限。應(yīng)用啟動時需要仍需要請求使用外部儲存。設(shè)置判斷是否請求權(quán)限與請求權(quán)限的函數(shù)

//判斷是否請求外部儲存權(quán)限

protected booleanshouldAskPermissions() {

return(Build.VERSION.SDK_INT> Build.VERSION_CODES.LOLLIPOP_MR1);

}

//當(dāng)最小sdk小于23時,請求外部儲存權(quán)限

@TargetApi(23)

protected voidaskPermissions() {

String[] permissions = {

"android.permission.READ_EXTERNAL_STORAGE",

"android.permission.WRITE_EXTERNAL_STORAGE"

};

intrequestCode =200;

requestPermissions(permissions,requestCode);

}

在onCreate函數(shù)中進行調(diào)用

External storage對其他應(yīng)用與用戶可訪問修改,其中文件分為兩類:public private

public:對其他用戶有用,應(yīng)用卸載時應(yīng)保留,例如下載的文件,拍攝的照片,保存的音樂

private:雖然技術(shù)上可以訪問,但對其他應(yīng)用無用,應(yīng)用卸載時自動刪除,主要為緩存

儲存在public時,使用getExternalStoragePublicDirectory()方法,參數(shù)為特定的文件類型

通過Environment.Directory獲得

//定義一個儲存在ExternalStorage的public的文件,參數(shù)必須為特定的文件類型:DIRECTORY_MUSIC 或者 DIRECTORY_PICTURES

Filesdcard= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

儲存在private時,使用getExternalStorageDirectory()方法,指定文件類型參數(shù)會儲存在private的參數(shù)文件夾下,不指定類型,儲存在private根目錄下

//在外部儲存private的根目錄下新建文件夾pictures

StringfilePath= Environment.getExternalStorageDirectory()+"/Pictures”;

獲取路徑后,按正常文件操作讀寫

寫入操作:

// 判斷設(shè)備sd卡是否存在

if(!sdcard.exists()){

Toast.makeText(getApplicationContext(),"sd卡不存在",Toast.LENGTH_SHORT).show();

return;

}

//文件不存在創(chuàng)建文件

if(!myFile.exists()){

try{

myFile.createNewFile();

}catch(IOException e) {

Log.e("文件創(chuàng)建失敗",e.getMessage());

e.printStackTrace();

}

//文件寫入操作

try{

FileOutputStream fos =newFileOutputStream(myFile);

OutputStreamWriter osw =newOutputStreamWriter(fos);

osw.write(et.getText().toString());

osw.flush();

fos.flush();

osw.close();

fos.close();

Toast.makeText(getApplicationContext(),"數(shù)據(jù)寫入成功",Toast.LENGTH_SHORT).show();

}catch(FileNotFoundException e) {

Log.e("文件沒找到",e.getMessage());

e.printStackTrace();

}catch(IOException e) {

Log.e("io錯誤",e.getMessage());

e.printStackTrace();

}

讀取操作:

// 判斷設(shè)備sd卡是否存在

if(!sdcard.exists()){

Toast.makeText(getApplicationContext(),"sd卡不存在",Toast.LENGTH_SHORT).show();

return;

}

//文件不存在創(chuàng)建文件

if(!myFile.exists()) {

try{

myFile.createNewFile();

}catch(IOException e) {

e.printStackTrace();

}

try{

FileInputStream fis =newFileInputStream(myFile);

InputStreamReader isr =newInputStreamReader(fis);

BufferedReader br =newBufferedReader(isr);

//StringBuilder儲存所有數(shù)據(jù)

StringBuilder strBuilder =newStringBuilder();

//臨時變量儲存每行數(shù)據(jù)

String line ="";

while((line = br.readLine()) !=null) {

//不為空,不斷追加

strBuilder.append(line);

}

br.close();

isr.close();

fis.close();

Toast.makeText(MainActivity.this,"數(shù)據(jù)讀取成功",Toast.LENGTH_SHORT).show();

tv.setText(strBuilder);

}catch(FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容