Android 文件数据储存之内部储存 + 外部储存

Android 文件数据储存之内部储存 + 外部储存

内部储存

Android官方API:在设备内存中存储私有数据。

内部储存:Android的内部储存位于系统中,是在手机内存中的文件,!!!不是SD卡(外部存储器)中的文件。内部储存文件默认的存放位置是data/data/files目录下,并且是私有的(private)。可以把它设置为公有的(public),则可以被其他的App访问。当一个应用卸载后,内部储存中的文件会被删除。

使用:内部储存空间十分有限,主要存放系统本身和系统应用的程序的数据,如SharedPreferences,SQLite数据库,普通应用应该尽量避免使用它。

下面主要了解3个文件夹:

核心原理:

Context提供了两个方法来打开数据文件里的文件IO流 FileInputStream openFileInput(String name)与 FileOutputStream(String name , int mode),这两个方法第一个参数 用于指定文件名,第二个参数指定打开文件的模式。具体有以下值可选:

MODE_PRIVATE:默认操作模式,表示该文件为私有数据,只能被应用本身访问,在此模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可 以使用Context.MODE_APPEND

MODE_APPEND:该模式比较人性化,它会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。

MODE_WORLD_READABLE:当前文件可被其他应用读取。!!

MODE_WORLD_WRITEABLE:当前文件可被其他应用写入。!!

!!官方API提示:自 API 级别 17 以来,常量 MODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE 已被弃用。从 Android N 开始,使用这些常量将会导致引发 SecurityException。这意味着,面向 Android N 和更高版本的应用无法按名称共享私有文件,尝试共享“file://”URI 将会导致引发 FileUriExposedException。 如果您的应用需要与其他应用共享私有文件,则可以将 FileProvider 与 FLAG_GRANT_READ_URI_PERMISSION 配合使用。

下面介绍一下data文件夹:

打开data文件夹(没有root的手机不能打开该文件夹),里边会有两个文件夹。

(1)app文件夹,存放着所有安装的App的Apk文件。

(2)data文件夹(内部存储),包括以下内容。

data/data/包名/shared_prefs:使用Sharedpreferenced将数据持久化存储于本地,存在这个文件夹中的xml文件里。

data/data/包名/databases:App里的数据库文件

data/data/包名/files:普通数据

data/data/包名/cache:缓存文件,手机内存不足时,会自动删除这里的数据。

Android系统提供了设备内部存储文件的读写操作API,完成文件的创建、内容的读出和写入(包括添加\修改)等。

读取一个内部存储的私有文件的步骤如下。

(1)调用openFilelnput(String filename),参数中填入文件名,会返回一个FileInputstream对象。

(2)使用FileInputstream流对象的read()方法读取字节。

(3)调用流的close()方法关闭流。

写入内部存储文件需要先获得一个文件的输出流,然后以write()的方式把待写入的信息写入到这个输出流中,最后关闭流。具体步骤如下。

(1)使用Context.openFileOutput(string name,int mode)方法,填入文件名和操作模式,获取FileOutputStream 对象.

(2)把待写入的内容通过write()方法写入到FileOutputStream 对象中。

(3)使用FileOutputStream 对象的close()关闭流。

其他文件操作方法如下。

getDir(String name , int mode):在应用程序的数据文件夹下获取或者创建name对应的子目录

File getFilesDir():获本文件系统的绝对路径。

String[] fileList():当前应用内部存储路径下的所有文件名。

boolean deleteFile(String name)删除一个指定文件名为name的文件。

File getDir():在内部存储空间中创建或打开一个已经存在的目录。

下面主要介绍一下文件主要操作类的方法

!!!在调用当前对象的Context后:

1. 保存内容到内部储存器中

可复制代码:

//保存内容到内部服务器中

public void save(String filename, String content)throws IOException{

//FileoutputStream myfos=context.openFileoutput(filename,Context.MODE_PRIVATE);

File file= new File(context.getFilesDir(), filename);

FileOutputStream myfos= new FileOutputStream(file);

myfos.write(content.getBytes());

myfos.close();

}

2. 通过文件名来获取内容

可复制代码:

/**

* 通过文件名来获取内容

* @param filename 文件名称

* @return 文件内容

*/

public String get(String filename) throws IOException {

FileInputStream fis = context.openFileInput(filename);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] data = new byte[1024];

int len = -1;

while ((len = fis.read(data)) != -1) {

baos.write(data, 0, len);

}

return new String(baos.toByteArray());

}

3.使用追加的方式在文件的末尾添加内容

可复制代码:

/**

* 使用追加的方式在文件的末尾添加内容

* @param filename 文件名

*@param content 追加的内容

*/

public void append(String filename, String content) throws IOException{

FileOutputStream myfos= context.openFileOutput(filename, Context.MODE_APPEND);

myfos.write(content.getBytes());

myfos.close();

}

4.删除文件

可复制代码:

/**

*删除文件

* @param filename 文件名

* @return 是否成功

*/

public boolean delete(String filename) {

return context.deleteFile(filename);

}

5.获取内部存储路径下的所有文件名

可复制代码:

/**

* 获取内部存储路径下的所有文件名

*@return 文件名数组

*/

public String [] queryAllfile(){

return context.fileList();

}

Java文件如下:

public class Internalstorage {

private Context context;

public Internalstorage(Context context) {

this.context = context;

}

//保存内容到内部服务器中

public void save(String filename, String content)throws IOException{

//FileoutputStream myfos=context.openFileoutput(filename,Context.MODE_PRIVATE);

File file= new File(context.getFilesDir(), filename);

FileOutputStream myfos= new FileOutputStream(file);

myfos.write(content.getBytes());

myfos.close();

}

/**

* 通过文件名来获取内容

* @param filename 文件名称

* @return 文件内容

*/

public String get(String filename) throws IOException {

FileInputStream fis = context.openFileInput(filename);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] data = new byte[1024];

int len = -1;

while ((len = fis.read(data)) != -1) {

baos.write(data, 0, len);

}

return new String(baos.toByteArray());

}

/**

* 使用追加的方式在文件的末尾添加内容

* @param filename 文件名

*@param content 追加的内容

*/

public void append(String filename, String content) throws IOException{

FileOutputStream myfos= context.openFileOutput(filename, Context.MODE_APPEND);

myfos.write(content.getBytes());

myfos.close();

}

/**

*删除文件

* @param filename 文件名

* @return 是否成功

*/

public boolean delete(String filename) {

return context.deleteFile(filename);

}

/**

* 获取内部存储路径下的所有文件名

*@return 文件名数组

*/

public String [] queryAllfile(){

return context.fileList();

}

}

外部储存

Android官方Api:每个兼容 Android 的设备都支持可用于保存文件的共享“外部存储”。 该存储可能是可移除的存储介质(例如 SD 卡)或内部(不可移除)存储。 保存到外部存储的文件是全局可读取文件,而且,在计算机上启用 USB 大容量存储以传输文件后,可由用户修改这些文件。

详解: 外部存储中的文件可以被用户或者其他应用程序读写的,其中有两种类型的文件。

(1).公共文件public fies这类文件可被自由访问,当应用被卸载之后,文件仍然保留。比如相机类应用被卸载后,照片仍然存在。公共文件有9大类,均为系统创建的文件夹,详细如下:

文件夹类型包括:

DCIM : 数字相机拍摄的照片

Music:用户音乐

Podcasts:音频/视频的剪辑片段

Ringtones:铃声

Alarms:闹钟的声音

Notification:通知

Pictures:所有的图片(不包括那些用照相机拍摄的照片)

Movies:所有的电影(不包括那些用摄像机拍摄的视频)和Download/其他下载的内容。

使用外部存储数据需要在应用程序中设置访问SD卡的权限,在AndroidManifest.xml中添加权限

首先判断是否存在可用的SD卡,Environment.getExternalStorageState()方法获取当前设备的状

态,判断是否为Environment.MEDIA_MOUNTED状态。

//判断SD卡是否存在

if(Environment.getExternalStorageState().equals(

Environment.MEDIA_MOUNTED)){

//记得最后要调用保存文件的方法实现保存

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

}else{

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

}

存储的文件路径使用Environment.getExternalStorageDirectory()方法获取当SD卡的根目录,进而访问相应的文件。创建公有文件的方法 :

File file=new File(Environment.getExternalStorageDirectory(),“boreseven”);

第二个参数为自己设置的名字

(2).私有文件Private files在应用被卸载后,私有文件也会被删除,类似与内部储存。获得外部储存私有文件路径的方法Context.getExternalFilesDir(),如:

如:File file = new File(this.getExternalFilesDir(Environment.DIRECTORY_PICTURES), “boreseven”);

下面小提一下两个方法:

1.保存文件到SD卡:

//保存文件到SD卡

public void saveToSDCard(String filename,String content){

File file=new File(Environment.getExternalStorageDirectory(),filename);

try {

FileOutputStream outputStream=new FileOutputStream(file);

outputStream.write(content.getBytes());

outputStream.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

2.读取SD卡文件:

//读取SD卡文件

public String readFileSdcard(String filename){

String res="";

try {

FileInputStream myfin=new FileInputStream(filename);

int length=myfin.available();

byte [] buff=new byte[length];

myfin.read(buff);

res= new String(buff, "UTF-8");

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return res;

}

拓展:点击按钮下载图片,可在系统相册中显示。

记得要添加权限,代码如下:

xml文件:

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity"

>

android:id="@+id/imageView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"

/>

android:id="@+id/mybutton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_centerHorizontal="true"

android:text="保存" />

java文件:

public class MainActivity extends Activity {

private ImageView imageView;

private Button mybutton;

private Handler handler;

private String URL="https://www.baidu.com/img/bd_logo1.png";//百度首页图片地址

@Override

protected void onCreate(final Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

handler=new Handler(new Handler.Callback() {

@Override

public boolean handleMessage(Message msg) {

switch (msg.what){

case 1://成功

byte[]result= (byte[]) msg.obj;

final Bitmap bitmap=BitmapFactory.decodeByteArray(result,0,result.length);//利用BitmapFactory将数据转换成bitmap类型

imageView.setImageBitmap(bitmap);//加载图片

imageView.setOnLongClickListener(new View.OnLongClickListener() {

@Override

public boolean onLongClick(View v) {

saveImageToGallery(MainActivity.this,bitmap);

return false;

}

});

}

return false;

}

});

OkHttpClient client=new OkHttpClient();//实例化

final Request request = new Request.Builder().url(URL).build(); //传入图片网址,,URL为自己定义好的网址。

client.newCall(request).enqueue(new Callback() {//实例化一个call的对象

@Override

public void onFailure(Call call, IOException e) {

}

@Override

public void onResponse(Call call, Response response) throws IOException {

Message message=handler.obtainMessage();//声明一个传递信息的Message

if (response.isSuccessful()){//成功

Log.e("YF", "onResponse: "+"YES" );//一个log,可以不写

message.what=1; //设置成功的指令为1

message.obj=response.body().bytes();//带入图片的数据

handler.sendMessage(message);//将指令和数据传出去

}else{//失败

Log.e("YF", "onResponse: "+"NO" );//一个log,可以不写

handler.sendEmptyMessage(0);//设置其他指令为零,然后进入handler

}

}

});

}

private void saveImageToGallery(Context context, Bitmap bmp) {

// 首先保存图片

File appDir = new File(Environment.getExternalStorageDirectory(),

"desheng");

if (!appDir.exists()) {

appDir.mkdir();

}

String fileName = System.currentTimeMillis() + ".jpg";

File file = new File(appDir, fileName);

try {

FileOutputStream fos = new FileOutputStream(file);

bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);

fos.flush();

fos.close();

} catch (FileNotFoundException e) {

Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show();

e.printStackTrace();

} catch (IOException e) {

Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show();

e.printStackTrace();

}

// 其次把文件插入到系统图库

try {

MediaStore.Images.Media.insertImage(context.getContentResolver(),

file.getAbsolutePath(), fileName, null);

Toast.makeText(context, "保存成功", Toast.LENGTH_SHORT).show();

} catch (FileNotFoundException e) {

Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show();

e.printStackTrace();

}

// 最后通知图库更新

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,

Uri.fromFile(new File(file.getPath()))));

}

private void initView() {

imageView = (ImageView) findViewById(R.id.imageView);

mybutton = (Button) findViewById(R.id.mybutton);

}

}

记得加网络权限,图片是加载的百度首页图片!!!

相关阅读

bt365体育在线 淘宝订单管理页面在哪里?一文带你全面了解!

淘宝订单管理页面在哪里?一文带你全面了解!

365dots LURKERS.IO - 免费在线玩!

LURKERS.IO - 免费在线玩!

bt365体育在线 什么是OPT?美国留学生如何正确使用OPT工作?Get OPT Job Offer Now!

什么是OPT?美国留学生如何正确使用OPT工作?Get OPT Job Offer Now!

365dots 微信聊天被限制多久会自动解除

微信聊天被限制多久会自动解除

365dots 夏天捕捉蜻蜓的方法

夏天捕捉蜻蜓的方法

bt365体育在线 新车磨合期到底该怎么开?4S店技师透露的正确做法

新车磨合期到底该怎么开?4S店技师透露的正确做法

365dots 热带雨林的“爱神”犀鸟

热带雨林的“爱神”犀鸟

365dots AI照片定位地理位置

AI照片定位地理位置

365娱乐app官方版下载 最良心的游戏有哪些 2024高人气良心手游排行榜

最良心的游戏有哪些 2024高人气良心手游排行榜