实验八 存储
一、实验目的
1.掌握Android内部数据读写的编程方法。
2. 了解Android关于SD卡操作的编程方法。
二、实验内容
1完成安卓系统内部数据存储的操作
2完成安卓系统外部(SD卡)数据存储的操作
三、实验仪器、设备
硬件:PC 微型计算机、8G以上内存、500G以上硬盘。
软件:Windows 7/10、Android Studio (Eclipse)、JDK、Android SDK。
四、实验步骤
(一)、内部存储
1.题目:
使用openFileOutput()方法和openFileInput()方法进行文件的创建和读写创建,界面如图1所示,创建文件名是“myFile.txt”,编辑框输入要写入的数据,点击写入按钮,将编辑框中内容写入到文件中,点击读出按钮读出文件内容显示在最下文本框中。
图1 内部数据存储
2.步骤:
① 建立android项目。
② 编辑布局文件activity_main.xml。
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
>
<EditText
android:id="@+id/etxtFileContent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
/>
<Button
android:id="@+id/btnWrite"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="写入"
/>
<Button
android:id="@+id/btnRead"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="读出"
/>
<TextView
android:id="@+id/txtInfoDisplay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="显示文件内容:"
/>
</TableLayout>
③按要求,编写按钮事件处理代码。
import androidx.appcompat.app.AppCompatActivity;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private EditText m_etxtFileContent=null;
private TextView m_txtInfoDisplay=null;
private String m_strFileName="myFile.txt";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_etxtFileContent=(EditText)findViewById(R.id.etxtFileContent);
m_txtInfoDisplay=(TextView)findViewById(R.id.txtInfoDisplay);
Button btnWrite=(Button)findViewById(R.id.btnWrite);
Button btnRead=(Button)findViewById(R.id.btnRead);
btnWrite.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
WriteData();
m_txtInfoDisplay.setText("未进行读出操作");
}
});
btnRead.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
ReadData();
}
});
}
//写入
private void WriteData()
{
String strFileContent=m_etxtFileContent.getText().toString();
FileOutputStream file=null;
try{
file=openFileOutput(m_strFileName,Context.MODE_APPEND);
file.write(strFileContent.getBytes());
file.flush();
file.close();
}
catch (Exception e) {
return;
}
}
//读出
private void ReadData()
{
FileInputStream file=null;
try{
file=openFileInput(m_strFileName);
if(file.available()==0)return;
byte[] byteFileContent=new byte[file.available()];
while(file.read(byteFileContent)!=-1);
m_txtInfoDisplay.setText(new String(byteFileContent));
}
catch (Exception e) {
return;
}
}
}
④运行,调试。
(二)、SDCard存储
1.题目:
在Sdcard卡上创建文件,界面如图所示,一共创建了4个activity文件,分别用于主界面、写入文本、读出文本和SD卡路径信息,在写入文本的编辑框输入要写入的数据,点击写入按钮,将编辑框中内容写入到文件中,点击读出按钮读出文件内容显示在文本框中。
图2 SD卡数据存储
2.步骤:
① 建立android项目。
② 编辑布局文件一共4个。
(1)activity_main.xml文件代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="20dp">
<Button
android:id="@+id/btn11"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:text="写入外部存储"
android:textAllCaps="false"
android:textColor="#B9197E"
android:textSize="24sp"
android:textStyle="bold" />
<Button
android:id="@+id/btn22"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="读取外部存储"
android:textAllCaps="false"
android:textColor="#B9197E"
android:textSize="24sp"
android:textStyle="bold" />
<Button
android:id="@+id/btn33"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="存储路径测试"
android:textAllCaps="false"
android:textColor="#B9197E"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
(2)activity_file_path.xml文件代码
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp">
<!--获取外部存储(即SD卡)目录路径-->
<TextView
android:id="@+id/tvnote_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="20dp"
android:layout_marginRight="2dp"
android:text="Environment.getExternalStorageDirectory().getAbsolutePath()的值为:"
android:textColor="#E91E63"
android:textSize="18sp"
android:textStyle="bold" />
<!--获取外部存储(即SD卡)状态-->
<TextView
android:id="@+id/tvnote_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="20dp"
android:layout_marginRight="2dp"
android:text="Environment.getExternalStorageState()的值为:"
android:textColor="#E91E63"
android:textSize="18sp"
android:textStyle="bold" />
<!--获取系统的公共存储路径-->
<TextView
android:id="@+id/tvnote_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="20dp"
android:layout_marginRight="2dp"
android:text="Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)的值为:"
android:textColor="#E91E63"
android:textSize="18sp"
android:textStyle="bold" />
<!--获取当前App的(外部存储的)私有存储路径-->
<TextView
android:id="@+id/tvnote_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="20dp"
android:layout_marginRight="2dp"
android:text="ggetExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)的值为:"
android:textColor="#E91E63"
android:textSize="18sp"
android:textStyle="bold" />
<!--获取SD卡的文档目录路径-->
<TextView
android:id="@+id/tvnote_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="20dp"
android:layout_marginRight="2dp"
android:text="Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)的值为:"
android:textColor="#E91E63"
android:textSize="18sp"
android:textStyle="bold" />
<!--获取SD卡的图片目录路径-->
<TextView
android:id="@+id/tvnote_6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginTop="20dp"
android:layout_marginRight="2dp"
android:text="Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)的值为:"
android:textColor="#E91E63"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
(3) activity_text_write.xml文件代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="20dp">
<EditText
android:id="@+id/edText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="48dp"
android:layout_marginRight="8dp"
android:text=""
android:textColor="#E91E63"
android:textSize="24sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="26dp"
android:orientation="horizontal">
<!--保存按钮-->
<Button
android:id="@+id/btn_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="保存文本到SD卡"
android:textColor="#E91E63"
android:textSize="24sp"
android:textStyle="bold" />
<!--取消按钮-->
<Button
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="取消"
android:textColor="#E91E63"
android:textSize="24sp"
android:textStyle="bold"/>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@android:color/holo_red_dark"
android:textSize="20sp"
android:textStyle="bold"></TextView>
</LinearLayout>
</ScrollView>
</LinearLayout>
(4)activity_text_read.xml文件代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="52dp"
android:orientation="horizontal">
<!--读取按钮-->
<Button
android:id="@+id/btn_read"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="读取"
android:textColor="#E91E63"
android:textSize="24sp"
android:textStyle="bold" />
<!--返回按钮-->
<Button
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="返回"
android:textColor="#E91E63"
android:textSize="24sp"
android:textStyle="bold"/>
</LinearLayout>
<TextView
android:id="@+id/tv_read"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="24dp"
android:layout_marginRight="8dp"
android:text="读取SD卡文本文件测试:"
android:textColor="#E91E63"
android:textSize="24sp"
android:textStyle="bold" />
</LinearLayout>
③按要求,编写事件处理代码,一共4个。
(1)MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_1 = (Button) findViewById(R.id.btn11);
Button btn_2 = (Button) findViewById(R.id.btn22);
Button btn_3 = (Button) findViewById(R.id.btn33);
btn_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this, TextWriteActivity.class);
startActivity(intent);
}
});
btn_2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this, TextReadActivity.class);
startActivity(intent);
}
});
btn_3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this, FilePathActivity.class);
startActivity(intent);
}
});
}
}
(2) FilePathActivity.java文件代码
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class FilePathActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_path);
// 获取外部存储(即SD卡)目录路径
String externalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath() .toString();
TextView tv_es_path = findViewById(R.id.tvnote_1);
tv_es_path.setText(tv_es_path.getText().toString() + externalStoragePath);
tv_es_path.setTextColor(Color.BLUE);
// 获取外部存储(即SD卡)状态
String esStatePath = Environment.getExternalStorageState().toString();
TextView tv_state_path = findViewById(R.id.tvnote_2);
tv_state_path.setText(tv_state_path.getText().toString() + esStatePath);
tv_state_path.setTextColor(Color.BLUE);
// 获取系统的公共存储路径
String esPublicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
TextView tv_public_path = findViewById(R.id.tvnote_3);
tv_public_path.setText(tv_public_path.getText().toString() + esPublicPath);
tv_public_path.setTextColor(Color.BLUE);
// 获取获取当前App的(外部存储的)私有存储路径
String esPrivatePath = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString();
TextView tv_private_path = findViewById(R.id.tvnote_4);
tv_private_path.setText(tv_private_path.getText().toString() + esPrivatePath);
tv_private_path.setTextColor(Color.BLUE);
// 获取SD卡的文档目录路径
String esDocPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).toString();
TextView tv_doc_path = findViewById(R.id.tvnote_5);
tv_doc_path.setText(tv_doc_path.getText().toString() + esDocPath);
tv_doc_path.setTextColor(Color.BLUE);
// 获取SD卡的图片目录路径
String esPicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
TextView tv_pic_path = findViewById(R.id.tvnote_6);
tv_pic_path.setText(tv_pic_path.getText().toString() + esPicPath);
tv_pic_path.setTextColor(Color.BLUE);
}
}
(3)TextReadActivity.java文件代码
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.FileInputStream;
public class TextReadActivity extends AppCompatActivity {
private String mPath;
private TextView read;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_read);
read = findViewById(R.id.tv_read);
Button btnRead = (Button) findViewById(R.id.btn_read);
Button btnBack = (Button) findViewById(R.id.btn_back);
// 获取当前App的私有存储目录
mPath = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/";
btnRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
showToast("SD卡已挂载!");
} else {
showToast("未发现已挂载的SD卡,请检查");
}
// 打开并显示选中的文本文件内容
String file_path = mPath + "a.txt";
String content = readText(file_path);
read.setText("文件内容如下:\n" + content);
read.setTextColor(Color.BLUE);
}
});
btnBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
finish();
}
});
}
private String readText(String path) {
String readStr = "";
try {
// 根据指定文件路径构建文件输入流对象
FileInputStream fis = new FileInputStream(path);
byte[] b = new byte[fis.available()];
// 从文件输入流读取字节数组
fis.read(b);
// 把字节数组转换为字符串
readStr = new String(b);
// 关闭文件输入流
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
// 返回文本文件中的文本字符串
return readStr;
}
private void showToast(String desc) {
Toast.makeText(this, desc, Toast.LENGTH_LONG).show();
}
}
(4)TextWriteActivity.java文件代码
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.FileOutputStream;
public class TextWriteActivity extends AppCompatActivity {
private EditText edText;
private String mPath;
private TextView display;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_write);
edText = findViewById(R.id.edText);
display = findViewById(R.id.tv_display);
Button btnSave = (Button) findViewById(R.id.btn_save);
Button btnCancal = (Button) findViewById(R.id.btn_cancel);
// 获取当前App的私有存储目录
mPath = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/";
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
String input = edText.getText().toString();
if (TextUtils.isEmpty(input)) {
showToast("输入文本不得为空!");
return;
}
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String file_path = mPath + "a.txt";
// 把文本字符串保存为文本文件
saveText(file_path, input);
display.setText("亲,输入文本的保存路径为:\n" + file_path);
display.setTextColor(Color.BLUE);
showToast("数据已写入SD卡文件");
} else {
showToast("未发现已挂载的SD卡,请检查");
}
}
});
btnCancal.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
finish();
}
});
}
private void saveText(String file_path, String input) {
try {
// 根据指定文件路径构建文件输出流对象
FileOutputStream fos = new FileOutputStream(file_path);
// 把字符串写入文件输出流
fos.write(input.getBytes());
// 关闭文件输出流
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void showToast(String desc) {
Toast.makeText(this, desc, Toast.LENGTH_SHORT).show();
}
}
④在清单文件中定义权限。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lg.sdfiledemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".FilePathActivity"></activity>
<activity android:name=".TextReadActivity" />
<activity android:name=".TextWriteActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- SD卡读写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAG" />
</manifest>
⑤运行,调试。
3.在“一、内部存储”例程中,保存数据的代码
private void WriteData()
{
String strFileContent=m_etxtFileContent.getText().toString();
FileOutputStream file=null;
try{
file=openFileOutput(m_strFileName,Context.MODE_APPEND);
file.write(strFileContent.getBytes());
file.flush();
file.close();
}
catch (Exception e) {
return;
}
}
五、实验思考题
1说明android studio对内部文件存储和SD卡存储主要有何区别?
答:使用内部存储是不需要权限的,内部存储属于应用的私有存储区域,其它应用不可访问,当应用被卸载时,内部存储中的文件也会被删除。外部存储分为公共目录和私有目录,外部存储是可以全局访问的,但需要申请权限。
2 在“一、内部存储”的例程中,保存数据的文件名称是什么?
答:myFile.txt