目录
10.数据存储技术(二)
2.文件存储
2-1.内部存储
2-2.外部存储
10.数据存储技术(二)
2.文件存储
在Java中提供了一套完整的I/O流体系, 通过这些I/O流可以很方便地访问磁盘上的文件内容。在Android中也同样支持以这种方式来访同手机存储器上的文件。
在Android中,主要提供了以下两种方式用于访问手机存储器上的文件。
(1)内部存储:使用FileOutputStream类提供的openFileOutput()方法和FileInputStream类提供的openFileInput()方法访问设备内部存储器上的文件。
(2)外部存储:使用Environment类的getExternalStorageDirectory()方法对外部存储上的文件进行数据读写。
2-1.内部存储
内部存储位于Android手机系统下的“/data/data/<包名>/files”目录中。使用Java提供的I/O流体系可以很方便地对内部存储的数据进行读写操作。其中,FileOutputStream 类的openFileOutput()方法用来打开相应的输出流;而FileInputStream类的openFileInput()方法用来打开相应的输入流。默认情况下,使用I/O流保存的文件仅对当前应用程序可见,对于其他应用程序(包括用户)是不可见的(即不能访问其中的数据)。
注:如果用户卸载了应用程序,则保存数据的文件也会一起被删除。
1.写入文件
要实现向内部存储器中写入文件,首先需要获取文件输出流对象FileOutputStream,这可以使用FileOutputStream类的openFileOutput()方法来实现,然后再调用FileOutputStream对象的write() 方法写入文件内容,再调用flush()方法清空缓存,最后调用close()方法关闭文件输出流对象。
FileOutputStream类的openFileOutput()方法的基本语法格式如下:
FileOutputStream openFile0utput(String name, int mode) throws FileNotFoundException
◆参数name:用于指定文件名称,该参数不能包含描述路径的斜杠。
◆参数mode:用于指定访问权限,可以使用如下取值:
◎MODE_PRIVATE:表示文件只能被创建它的程序访问。
◎MODE_APPEND: 表示追加模式,如果文件存在,则在文件的结尾处添加新数据,否则创建文件。
◎MODE_WORLD_READABLE:表示可以被其他应用程序读,但不能写。
◎MODE_WORLD_WRITEABLE:表示可以被其他应用程序读和写。
openFileOutput()方法的返回值为FileOutputStream对象。
注:openFileOutput()方法需要抛出FileNotFoundException异常。
例如,创建一个文件 (myfile.txt) ,该文件只能被创建它的程序访问,代码如下:
try {
FileoutputStream fos = openFileOutput("myfile.txt",MODE_PRIVATE);//获得文件输出流
fos.write("www.baidu.com".getBytes());//保存网址
fos.flush();//清空缓存
fos.close();//关闭文件输出流
} catch (FileNotFoundException e) {
e. printStackTrace();
}
在上面的代码中,FileOutputStream 对象的write()方法用于将数据写入文件; flush()方法用于将缓存中的数据写入文件,清空缓存;close() 方法用于关闭FileOutputStream 对象。
2.读取文件
要实现读取内部存储器中的文件,首先需要获取文件输入流对象FileInputStream,这可以使用FileInputStream类的openFileInput()方法来实现,然后再调用FileInputStream对象的readO方法读取文件内容,最后调用close() 方法关闭文件输入流对象。
FileInputStream类的openFileInput() 方法的基本语法格式如下:
FileInputStream openFileInput(String name) throws FileNotFoundException
该方法只有一个参数,用于指定文件名称,同样不可以包含描述路径的斜杠,而且也需要抛出FileNotFoundException异常。返回值为FileInputStream对象。
例如,读取文件myfile.txt的内容,代码如下:
FileInputStream fis = openFileInput("myfile.txt");//获得文件输入流
byte[ ] buffer = new byte[fis.available()];//定义保存数据的数组
fis.read(buffer);//从输入流中读取数据
例:
MainActivity.java
package com.example.internalstoragenotepad;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
byte[] buffer = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar=getSupportActionBar();
actionBar.hide();
EditText editText=(EditText) findViewById(R.id.main_et1);
ImageButton btn_save=(ImageButton) findViewById(R.id.main_ib1);
ImageButton btn_cancel=(ImageButton) findViewById(R.id.main_ib2);
btn_save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FileOutputStream fos=null;//定义文件输出流
String text = editText.getText().toString();//获取文本信息
try {
//获得文本输出流,并指定文件保存的位置
fos=openFileOutput("demo",MODE_PRIVATE);
fos.write(text.getBytes());//保存文本信息
fos.flush();//清除缓存
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fos!=null){//输出流不为空时
try {
fos.close();//关闭文件输出流
Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
//第二次打开应用时显示上一次所保存的文本信息
FileInputStream fis=null;//定义文件输入流
try {
fis=openFileInput("demo");//获得文件输入流
buffer=new byte[fis.available()];//保存数据的数组
fis.read(buffer);//从输入流中读取数据
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fis!=null){//输入流不为空时
try {
fis.close();//关闭输入流
String data=new String(buffer);//获得数组中保存的数据
editText.setText(data);//将读取的数据显示到编辑框中
} catch (IOException e) {
e.printStackTrace();
}
}
}
btn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();//退出应用
}
});
}
}
注:运行本实例,保存备忘录信息后,demo文件将被保存在“data\data<项目资源包名>\files\”目录下。由于系统安全问题该文件无法查看,只能在本应用中读取。
2-2.外部存储
每个Android设备都支持共享的外部存储用来保存文件,它也是手机中的存储介质。保存在外部存储的文件都是全局可读的,而且在用户使用USB连接电脑后,可以修改这些文件。在Android程序中,对外部存储的文件进行操作时,需要使用Environment 类的getExternalStorageDirectory()方法,该方法用来获取外部存储器的目录。
注:为了读、写外部存储上的数据,必须在应用程序的全局配置文件(AndroidManifest.xml )中添加读、写外部存储的权限。配置如下:
<!-- 开启在外部存储中创建与删除文件权限-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 开启向外部存储读取数据权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 开启向外部存储写入数据权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
例:
MainActivity.java
package com.example.externalstoragenotepad;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
byte[] buffer = null; //定义保存数据的数组
File file; //声明一个文件对象,用来指定外部存储文件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar=getSupportActionBar();
actionBar.hide();
final EditText etext = (EditText) findViewById(R.id.main_puttext); //获取用于填写记事本信息的编辑框组件
ImageButton btn_save = (ImageButton) findViewById(R.id.main_save); //获取保存按钮
ImageButton btn_abolish = (ImageButton) findViewById(R.id.main_cancel); //获取取消按钮
//在外部存储根目录上创建文件
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "Text.text");
btn_save.setOnClickListener(new View.OnClickListener() { //实现外部存储填写的文本信息
@Override
public void onClick(View v) {
FileOutputStream fos = null; //定义文件输出流
String text = etext.getText().toString(); //获取文本信息
try {
fos = new FileOutputStream(file); //获得文件输出流,并指定文件保存的位置
fos.write(text.getBytes()); //保存文本信息
fos.flush(); //清除缓存
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close(); //关闭文件输出流
Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
//实现第二次打开应用时显示上一次所保存的文本信息
FileInputStream fis = null; //定义文件输入流
try {
fis = new FileInputStream(file); //获得文件输入流
Log.i("路径",""+file);
buffer = new byte[fis.available()]; //保存数据的数组
fis.read(buffer); //从输入流中读取数据
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close(); //关闭输入流
String data = new String(buffer); // 获得数组中保存的数据
etext.setText(data); //保存到编辑框中
} catch (IOException e) {
e.printStackTrace();
}
}
}
btn_abolish.setOnClickListener(new View.OnClickListener() { //实现单击取消按钮,退出应用
@Override
public void onClick(View v) {
finish(); //退出应用
}
});
}
}
Mainfest.xml
<!--读取外部存储权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--写入外部存储权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--在外部存储中创建与删除文件权限-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
注:要在模拟器的应用权限管理中允许应用读取存储空间!
文件存储目录:mnt\sdcard