資料儲存與存取之-檔案儲存讀寫
本節引言:
嘿嘿,看到這個題目,相信部分讀者會問,你前面的Fragment寫完了嗎?嗯,沒寫完,因為想例子,需要 一點時間,為了提高效率,所以決定像多線程一樣,並發的來寫教程,這樣可能可以加快寫教程的進度, 到現在為止,剛好寫了60篇,離完成入門教程還很遠呢,而前面也說過,想在一個半到兩個月之內完成 這套教程,今天已經9.1號了,要加吧勁~好的,廢話就這麼多,本節要跟大家介紹的是Android資料儲存與 存取方式中的一個-檔案儲存與讀寫,當然除了這種方式外,我們可以儲存到SharedPreference,資料庫, 或者Application中,當然這些後面都會講,嗯,開始本節內容~
#1.Android檔案的操作模式
學過Java的同學都知道,我們新建文件,然後就可以寫入資料了,但Android卻不一樣,因為Android是 基於Linux的,我們在讀寫檔案的時候,還要加上檔案的操作模式,Android中的操作模式如下:
#2 .檔案的相關操作方法3.檔案讀寫的實作
Android中的檔案讀寫和Java中的檔案I/ O相同,流程也很簡單,下面我們來寫個簡單的範例:
實作效果圖:
PS:這裡用的是模擬器,因為筆者的N5並沒有root,看不到檔案的儲存目錄,下面我們開啟DDMS 的File Exploer可以看到,在data/data/<套件名稱>/file中有我們寫入的檔案:
##我們可以點擊右上角的回應圖示將檔案匯入電腦中,並且開啟驗證寫入的內容:
程式碼實作:#首先是佈局檔案:
main_activity.xml<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.jay.example.filedemo1.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nametitle" />
<EditText
android:id="@+id/editname"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/detailtitle" />
<EditText
android:id="@+id/editdetail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minLines="2" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnsave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnwrite" />
<Button
android:id="@+id/btnclean"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnclean" />
</LinearLayout>
<Button
android:id="@+id/btnread"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnread" />
</LinearLayout>
然後我們來寫一個檔案協助類別:
/**
* Created by Jay on 2015/9/1 0001.
*/
public class FileHelper {
private Context mContext;
public FileHelper() {
}
public FileHelper(Context mContext) {
super();
this.mContext = mContext;
}
/*
* 这里定义的是一个文件保存的方法,写入到文件中,所以是输出流
* */
public void save(String filename, String filecontent) throws Exception {
//这里我们使用私有模式,创建出来的文件只能被本应用访问,还会覆盖原文件哦
FileOutputStream output = mContext.openFileOutput(filename, Context.MODE_PRIVATE);
output.write(filecontent.getBytes()); //将String字符串以字节流的形式写入到输出流中
output.close(); //关闭输出流
}
/*
* 这里定义的是文件读取的方法
* */
public String read(String filename) throws IOException {
//打开文件输入流
FileInputStream input = mContext.openFileInput(filename);
byte[] temp = new byte[1024];
StringBuilder sb = new StringBuilder("");
int len = 0;
//读取文件内容:
while ((len = input.read(temp)) > 0) {
sb.append(new String(temp, 0, len));
}
//关闭输入流
input.close();
return sb.toString();
}
}
最後是
,我們在這裡完成相關操作:public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editname;
private EditText editdetail;
private Button btnsave;
private Button btnclean;
private Button btnread;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = getApplicationContext();
bindViews();
}
private void bindViews() {
editdetail = (EditText) findViewById(R.id.editdetail);
editname = (EditText) findViewById(R.id.editname);
btnclean = (Button) findViewById(R.id.btnclean);
btnsave = (Button) findViewById(R.id.btnsave);
btnread = (Button) findViewById(R.id.btnread);
btnclean.setOnClickListener(this);
btnsave.setOnClickListener(this);
btnread.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnclean:
editdetail.setText("");
editname.setText("");
break;
case R.id.btnsave:
FileHelper fHelper = new FileHelper(mContext);
String filename = editname.getText().toString();
String filedetail = editdetail.getText().toString();
try {
fHelper.save(filename, filedetail);
Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();
}
break;
case R.id.btnread:
String detail = "";
FileHelper fHelper2 = new FileHelper(getApplicationContext());
try {
String fname = editname.getText().toString();
detail = fHelper2.read(fname);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
break;
}
}
}
4.讀取SD卡上的檔案
: 程式碼範例: 執行效果圖: 同樣開啟DDMS的File Explorer,在舊版的系統上我們可以直接在mmt\sdcard上找到,但新版本
的就可能需要我們自己找找了,首先我們來到這條路徑下: #點開sdcard,但沒東西,我們繼續找嘮叨後面這個/storage /emulated/legacy下找: 好吧,他又跳到別的地方去了,我們繼續找/storage/shell/emilated/0 果然找到了,我們在SD卡里產生的test.txt!匯出到電腦看下裡面的內容: 嘿嘿,果然讀寫SD卡成功~接下來我們來看下程式碼是怎麼寫的: #程式碼實作: main_activity.xml: 接著我們來寫一個SD操作類別:SDFileHelper.java 接著MainActivity.java實作相關邏輯: 最後別忘記在AndroidManifest.xml寫上讀寫SD卡的權限哦! 如果是真機調試的話通常都是可以的,對於原生虛擬機的話就問題多多了,再我們前面使用
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)可能
一直回傳的是false,就是SD卡不存在,這是主要的問題,現在新版的SDK都會在
建立AVD的時候會同時申請一塊SD卡的儲存區域的 #對於舊版的sdk或其他原因可能需要手動關聯下sd卡,設定如下: ②來到avd鏡像所在的路徑下,複製sdcard.img的路徑: 例如我的:-sdcard C:\Users\Administrator.android\avd\Jay4.2.avd\sdcard .img ③接著點擊來到以下介面: 最後apply以下,然後Run就可以了! 相信大家對兩個資料夾並不陌生,如果我們不想自己的檔案被編譯成二進位檔案的話,
我們可以把檔案放到這兩個目錄下,而兩者的區別如下: 讀取檔案資源: #res/raw: assets: #好的,關於Android的資料儲存與存取的第一節-檔案讀寫就到這裡,如果在學習本文中
遇到什麼問題,或覺得有些紕漏的地方,歡迎提出,萬分感激,謝謝~<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.jay.example.filedemo2.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清输入文件名" />
<EditText
android:id="@+id/edittitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="文件名" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清输入文件内容" />
<EditText
android:id="@+id/editdetail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="文件内容" />
<Button
android:id="@+id/btnsave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存到SD卡" />
<Button
android:id="@+id/btnclean"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清空" />
<Button
android:id="@+id/btnread"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="读取sd卡中的文件" />
</LinearLayout>
/**
* Created by Jay on 2015/9/1 0001.
*/
public class SDFileHelper {
private Context context;
public SDFileHelper() {
}
public SDFileHelper(Context context) {
super();
this.context = context;
}
//往SD卡写入文件的方法
public void savaFileToSD(String filename, String filecontent) throws Exception {
//如果手机已插入sd卡,且app具有读写sd卡的权限
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
//这里就不要用openFileOutput了,那个是往手机内存中写数据的
FileOutputStream output = new FileOutputStream(filename);
output.write(filecontent.getBytes());
//将String字符串以字节流的形式写入到输出流中
output.close();
//关闭输出流
} else Toast.makeText(context, "SD卡不存在或者不可读写", Toast.LENGTH_SHORT).show();
}
//读取SD卡中文件的方法
//定义读取文件的方法:
public String readFromSD(String filename) throws IOException {
StringBuilder sb = new StringBuilder("");
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
//打开文件输入流
FileInputStream input = new FileInputStream(filename);
byte[] temp = new byte[1024];
int len = 0;
//读取文件内容:
while ((len = input.read(temp)) > 0) {
sb.append(new String(temp, 0, len));
}
//关闭输入流
input.close();
}
return sb.toString();
}
}
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private EditText editname;
private EditText editdetail;
private Button btnsave;
private Button btnclean;
private Button btnread;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = getApplicationContext();
bindViews();
}
private void bindViews() {
editname = (EditText) findViewById(R.id.edittitle);
editdetail = (EditText) findViewById(R.id.editdetail);
btnsave = (Button) findViewById(R.id.btnsave);
btnclean = (Button) findViewById(R.id.btnclean);
btnread = (Button) findViewById(R.id.btnread);
btnsave.setOnClickListener(this);
btnclean.setOnClickListener(this);
btnread.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnclean:
editdetail.setText("");
editname.setText("");
break;
case R.id.btnsave:
String filename = editname.getText().toString();
String filedetail = editdetail.getText().toString();
SDFileHelper sdHelper = new SDFileHelper(mContext);
try
{
sdHelper.savaFileToSD(filename, filedetail);
Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();
}
catch(Exception e){
e.printStackTrace();
Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();
}
break;
case R.id.btnread:
String detail = "";
SDFileHelper sdHelper2 = new SDFileHelper(mContext);
try
{
String filename2 = editname.getText().toString();
detail = sdHelper2.readFromSD(filename2);
}
catch(IOException e){e.printStackTrace();}
Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
break;
}
}
}
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
5.關於原生模擬器SD卡的問題
①找到創建好的avd的鏡像的路徑:
點擊打開avd介面,點擊detail,查看avd鏡像的目錄下#6.讀取raw與assets資料夾下的檔案
InputStream is =getResources().openRawResource(R.raw.filename);
AssetManager am = getAssets();
InputStream is = am.open("filename");
程式碼下載:
本節小結: