2014-11-09 19:15:00 wj903829182 阅读数 1776
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19197 人正在学习 去看看 任苹蜻

    在android系统中主要提供了三种方式用于简单的实现数据持久化功能,即文件存储,SharePreference存储以及数据库存储。当然还可以把数据保存到SD卡中。

  文件存储是android中最基本的一种数据存储方式,它不对存储的内容进行任何的格式话处理,所有数据都是原封不动地保存到文件当中的,因而比较适合用于存储一些简单的文本数据或二进制数据。

     Context类中提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中。这个方法接收两个参数,第一个参数是文件的名,在创建文件的时候使用的就是这个名称,注意这里指定的文件名不包含路径,因为所有的文件都是默认存储到/data/data/<package>/files/目录下的。第二个参数是文件的操作模式,主要有2种模式可选,MODE_PRIVATE和MODE_APPEND.其中MODE_PRIVATE是默认的操作模式,表示当指定同样文件名的时候,所写入的内容将会覆盖原文件中的内容,而MODE_APPEND则表示如果该文件已存在就往文件里面追加内容,不存在就创建新文件。

     openFileOutput()方法返回的是一个FileOutputStream对象,得到这个对象之后就可以使用java流的方式将数据写入到文件中了。



把数据保存到文件中


创建一个android项目,项目名为FilePersistenceTest,并修改activity_main.xml中的代码,代码如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >

   <EditText 
       android:id="@+id/edit"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:hint="type something here"
       />

</LinearLayout>


下面我们要做的是,在活动销毁的时候,保存数据,把数据保存到文件当中。修改MainActivity中的代码:

package com.jack.filepersistencetest;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.widget.EditText;

public class MainActivity extends Activity {

	private EditText editText;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		editText = (EditText) findViewById(R.id.edit);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public void save(String inputText){
		FileOutputStream fileOutputStream=null;//文件输出流对象
		BufferedWriter bufferedWriter=null;//字符缓冲流对象
		try {
			//初始化文件输出流对象
			fileOutputStream=openFileOutput("datafile", Context.MODE_PRIVATE);
			//初始化字符缓冲流对象
			bufferedWriter=new BufferedWriter(new OutputStreamWriter(fileOutputStream));
			//向缓冲内存中写入字符串
			bufferedWriter.write(inputText);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try{
				if(bufferedWriter!=null){
					bufferedWriter.close();//关闭文件
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		String inputText=editText.getText().toString();//获取到文本框里面的内容
		save(inputText);//保存文本框中的信息
	}
	
	
	
	
}


在活动销毁的时候调用onDestroy方法的时候调用save方法保存文本框里面的内容。运行程序,在文本框中输入hello world,如下图:



然后按下back键关闭程序,这时我们输入的内容就已经保存到文件中了。我们可以打开ddms的file explorer来查看。在file explorer中进入到/data/data/com.jack.filepersistencetest/files/目录下面,可以看到生成了datafile文件,如下图:




然后点击上图中右边最左边的按钮将文件导出到电脑上,然后用文本编辑器打开文件,可以看到里面的内容如下:

可以证实文本框里面的内容确实已经保存到文件中了。



从文件中读取数据

    类似将数据存储到文件中Context类中还提供了一个openFileInput方法,用于从文件中读取数据。这个方法比较简单,只接收一个参数,即要读取的文件名,然后系统会自动到/data/data/<package>/files/目录下加载这个文件,并返回一个FileInputStream对象,得到了这个对象之后再通过java流的方式就可以将数据读取出来了。

修改MainActivity中的代码,修改如下所示:

package com.jack.filepersistencetest;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;
import android.view.Menu;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

	private EditText editText;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		editText = (EditText) findViewById(R.id.edit);
		
		String inputText=load();
		if(!TextUtils.isEmpty(inputText)){
			editText.setText(inputText);
			editText.setSelection(inputText.length());
			Toast.makeText(this, "Restoring succeeded",
					Toast.LENGTH_SHORT).show();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public void save(String inputText){
		FileOutputStream fileOutputStream=null;//文件输出流对象
		BufferedWriter bufferedWriter=null;//字符缓冲流对象
		try {
			//初始化文件输出流对象
			fileOutputStream=openFileOutput("datafile", Context.MODE_PRIVATE);
			//初始化字符缓冲流对象
			bufferedWriter=new BufferedWriter(new OutputStreamWriter(fileOutputStream));
			//向缓冲内存中写入字符串
			bufferedWriter.write(inputText);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try{
				if(bufferedWriter!=null){
					bufferedWriter.close();//关闭文件
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		String inputText=editText.getText().toString();//获取到文本框里面的内容
		save(inputText);//保存文本框中的信息
	}
	
	
	public String load(){
		FileInputStream in=null;//文件输入流
		BufferedReader reader=null;//字符缓冲流
		StringBuffer content=new StringBuffer();//StringBuffer对象
		try {
			in=openFileInput("datafile");//获得文件输入流
			reader=new BufferedReader(new InputStreamReader(in));//获得缓冲对象
			String line="";//
			while((line=reader.readLine())!=null){//读取一行内容
				content.append(line);//把读取的内容添加到content
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(reader!=null){
				try {
					reader.close();//关闭读取流
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		return content.toString();//返回字符串
		
	}
	
}

setSelection方法将输入光标移动到文本的末尾位置以便于继续输入,然后弹出一句还原成功的提示。

TextUtils.isEmpty()方法可以一次性进行2种值的判断,当传入的字符串等于null或等于空字符串的时候,这个方法都会返回true,从而使我们不需要单独去判断这两种空值。

重新运行程序,效果如下:




文件存储不适合用来保存一些比较复杂的数据,更复杂的数据的保存方法,我将在后面就行总结。



转载请注明来至:http://blog.csdn.net/j903829182/article/details/40924441



2018-12-17 17:17:13 wynnie 阅读数 371
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19197 人正在学习 去看看 任苹蜻

Android系统中主要提供了3种方式用于简单地实现数据持久化功能,即文件存储,SharedPreferences存储,数据库存储。下面我先介绍下文件存储。

文件存储是Android中最基本的一种数据存储方式,它比较适合用于存储一些简单的文本数据或二进制数据。

1.将数据存储到文件中

Context类中提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中。

下面我们编写一个简单的例子,学习一下如何在Android项目中使用文件存储的技术。首先创建一个FilePersistenceTest项目,修改activity_main.xml中代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >
<EditText
    android:id="@+id/edit"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Type something here"
    />
</LinearLayout>

在局部中加入了一个EditText,用于输入文本内容。

修改MainActivity中的代码,如下:

public class MainActivity extends Activity {
    private EditText edit;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取EditText实例
        edit=(EditText)findViewById(R.id.edit);

    }
    protected  void onDestroy(){
        super.onDestroy();
        //获取EditText中的内容
        String inputText=edit.getText().toString();
        //在活动销毁前,调用save()方法把输入的内容存储到文件中
        save(inputText);
    }

    private void save(String inputText) {
        FileOutputStream out=null;
        BufferedWriter writer=null;
        try {
            //openFileOutput()方法,将数据存储到指定的文件中
            // 第一个参数,文件命名为data,没有包含路径,因为所有文件默认存储到/data/data/<packagename>/file/目录
            // 第二个参数,文件的操作模式MODE_PRIVATE,表示当指定同样文件名时,所写入的内容将会覆盖原文件的内容
            //通过openFileOutput()方法得到FileOutputStream对象,再借助它构建出一个OutputStreamWriter对象,
            // 接着再使用OutputStreamWriter构建出一个BufferedWriter对象
            // 就使用BufferedWriter对象将数据写入文件
            out=openFileOutput("date", Context.MODE_PRIVATE);
            writer=new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);
        }  catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if(writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


}

运行程序,输入内容后,再按下Back键关闭程序,输入的内容已保存到文件中。

可通过Android Device Monnitor工具查看,如果导航栏中Tools—>Android找不到Android Device Monnitor,可直接在右边的点击搜索图标搜索Android Device Monnitor,点击了Android Device Monnitor—>File Explorer—>/data/data/<com.example.filepersistencetest>/files/目录,可以看到生成了一个data文件,点击可查看。也可点击右上方左按钮将文件导出到电脑上,使用记事本打开文件。

 

2.从文件中读取数据 

类似于将数据存储到文件中,Context类中还提供了一个openFileInput()方法,用于从文件中读取数据。这个方法只接收一个参数,即要读取的文件名。修改MainActivity代码如下:

public class MainActivity extends Activity {
    private EditText edit;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取EditText实例
        edit=(EditText)findViewById(R.id.edit);
        String inputText=load();
        //调用load()读取文本内容,如果读到的内容不为空,调用EditText的setText()方法,将内容填充到EditText里,
        //并调用setSelection()将输入光标移动到文本末尾以便于继续输入。
        //然后弹出一句还原成功的提示。
        if(!TextUtils.isEmpty(inputText)){
            edit.setText(inputText);
            edit.setSelection(inputText.length());
            Toast.makeText(this,"Restoring succeeded",Toast.LENGTH_SHORT).show();

        }
    }
    //读取文件中存储的文本内容
    private String load() {
        FileInputStream in=null;
        BufferedReader reader=null;
        StringBuilder content=new StringBuilder();
        try {
            in=openFileInput("data");
            reader=new BufferedReader(new InputStreamReader(in));
            String line="";
            while((line= reader.readLine())!=null){
                content.append(line);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }finally {
            //
            if(reader!=null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return content.toString();
    }

    protected  void onDestroy(){
        super.onDestroy();
        //获取EditText中的内容
        String inputText=edit.getText().toString();
        //在活动销毁前,调用save()方法把输入的内容存储到文件中
        save(inputText);
    }

    private void save(String inputText) {
        FileOutputStream out=null;
        BufferedWriter writer=null;
        try {
            //openFileOutput()方法,将数据存储到指定的文件中
            // 第一个参数,文件命名为data,没有包含路径,因为所有文件默认存储到/data/data/<packagename>/file/目录
            // 第二个参数,文件的操作模式MODE_PRIVATE,表示当指定同样文件名时,所写入的内容将会覆盖原文件的内容
            //通过openFileOutput()方法得到FileOutputStream对象,再借助它构建出一个OutputStreamWriter对象,
            // 接着再使用OutputStreamWriter构建出一个BufferedWriter对象
            // 就使用BufferedWriter对象将数据写入文件
            out=openFileOutput("date", Context.MODE_PRIVATE);
            writer=new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);
        }  catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            if(writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


}

重新运行程序,内容会还原到EditText。

这样,我们就已经把文件存储方面的知识学习完了,所用到的核心技术就是Context类中提供的openFileInput()和openFileOutput(),之后就是利用Java的各种流来进行读写操作。

初次写博客,欢迎小哥哥小姐姐提出宝贵的意见~

2017-09-07 11:26:53 qq_28572235 阅读数 1316
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19197 人正在学习 去看看 任苹蜻

文件存储是Android中最基本的一种数据存储方式,它不对数据进行任何的格式化处理,所有的数据都是原封不动的保存在文件中去,因而比较适合用于存储一些简单的文本数据或二进制数据,如果你想使用文件存储的方式来保存一些较为复杂的文本数据,就需要定义一套自己的格式规范,这样可以方便之后将数据从文件中重新解析出来.
1.将数据存储到文件
Context类中提供了一个openFileOupput()方法,可以用于将数据存储到指定的文件中去,这个方法有两个参数,第一个参数是文件名,在文件创建的时候使用的就是这个名字,注意这里指定的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data/packagename/files/目录下的,第二个参数是文件的操作模式,主要有两种模式,MODE_PRIVATE和MODE_APPEND.其中MODE_PRIVATE是默认操作模式,表示当指定同样的文件名的时候,所写入的内容将会覆盖原文件中的内容,而MODE_APPEND则表示如果文件已经存在,就往文件里面追加内容,不存在就创建新文件,
openFileOutput()方法返回的是一个FileOutputStream对象,得到这个对象之后就可以使用Java流的方式将数据写入到文件中去
activity_main.xml代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        andorid:hint="Type something here"/>
</LinearLayout>

MainActivity.class代码:

public class MainActivity extends AppCompatActivity{
    private EditText edit;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edit = (EditText)findViewById(R.id.edit);
    }
    @Override
    protected void onDestroy(){
        super.onDestroy();
        String inputText = edit.getText().toString();
        save(inputText);
    }
    public void save(String inputText){
        FileOutputStream out = null;
        BufferedWriter writer = null;
        try{
            out = openFileOutput("data", Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(writer != null) {
                    writer.close();
                }
            } catch(IOException e) {
                e.printStackTrace();
            }
        }
    }
}

可以看到,首先我们在onCreate()方法中获取EditText实例,然后重写onDestroy()方法,这样就可以保证在活动销毁之前一定会调用这个方法,在onDestroy()方法中我们获取到EditText中输入的内容,并调用save()方法把输入的内容存储到文件中,文件名为data.
save()中的代码是通过openFileOutput()方法能够得到一个FileOutputStream对象,然后借助它构建出一个OutputStreamWriter对象,接着再使用OutputStreamWriter构建出一个BufferedWriter对象,这样你就可以通过BufferedWriter来将文本内容写到文件中去了.

2.从文件中读取数据
类似于将数据存储到文件中,Context类中还提供了一个openFileInput()方法,用于从文件中读取数据,这个方法比openFileOutput()方法简单一些,它只接收一个参数,即要读取的文件名,然后系统会自动到/data/data/packagename/files/目录下去加载这个文件,并返回一个FileInputStream对象,得到这个对象之后再通过Java流的方式就可以将数据读取出来,
修改上面MainActivity.class中的代码,使得重新启动程序的时候EditText中能够保留上次输入的内容

public class MainActivity extends AppCompatActivity{
    private EditText edit;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edit = (EditText)findViewById(R.id.edit);
        String inputText = load();
        if(!TextUtils.isEmpty(inputText)){
            edit.setText(inputText);
            edit.setSelection(inputText.length());
            Toast.makeText(this,"Restoring succeeded",Toast.LENGTH_SHORT).show();
        }
    }
    ...
    public String load(){
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder content = new StringBuilder();
        try {
            in = openFileInput("data");
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while((line = reader.readLine()) != null){
                content.append(line);
            }
        } catch (IOException e){
            e.printStackTrace();
        } finally{
            if(reader != null){
                try{
                    reader.close();
                } catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
        return content.toString();
    }
}

在onCreate()方法中调用load()方法来读取文件中存储的文本内容,如果读到的内容不为null,就调用EditText的setText()方法将内容填充到EditText中,并调用setSelection()方法将光标移动到文本的末尾位置以便于继续输入,然后弹出一句还原成功的提示.
load()方法通过openFileInput()方法获取到一个FileInputStream对象,然后借助它又构建出一个InputStreamReader对象,接着再使用InputStreamReader构建出一个BufferedReader对象,这样我们就可以通过BufferedReader进行一行行的读取,把文件中所有的文本内容全部读取出来,并存放在一个StringBuilder对象中,最后将读取到的内容返回就可以了.
上面代码在对字符串进行判空的时候使用了TextUtils.isEmpty()方法,这是一个非常好用的方法,它可以一次性进行两种空值的判断,当传入的字符串等于null或等于空字符串的时候,这个方法都会返回true,从而使得我们不需要先单独判断这两种空值再使用逻辑运算符连接起来.

2017-04-26 18:42:57 ylyg050518 阅读数 537
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19197 人正在学习 去看看 任苹蜻

关于Android中几个常用文件路径的介绍

Android 使用与其他平台上基于磁盘的文件系统类似的文件系统。 本课程讲述如何使用 Android 文件系统通过 File API 读取和写入文件。

File 对象适合按照从开始到结束的顺序不跳过地读取或写入大量数据。 例如,它适合于图片文件或通过网络交换的任何内容。

本课程展示如何在您的应用中执行基本的文件相关任务。本课程假定您熟悉 Linux 文件系统的基础知识和 java.io 中的标准文件输入/输出 API。

选择内部或外部存储

所有 Android 设备都有两个文件存储区域:“内部”和“外部”存储。这些名称在 Android 早期产生,当时大多数设备都提供内置的非易失性内存(内部存储),以及移动存储介质,比如微型 SD 卡(外部存储)。一些设备将永久性存储空间划分为“内部”和“外部”分区,即便没有移动存储介质,也始终有两个存储空间,并且无论外部存储设备是否可移动,API 的行为均一致。以下列表汇总了关于各个存储空间的实际信息。

内部存储:

它始终可用。
只有您的应用可以访问此处保存的文件。
当用户卸载您的应用时,系统会从内部存储中移除您的应用的所有文件。

当您希望确保用户或其他应用均无法访问您的文件时,内部存储是最佳选择。

外部存储:

它并非始终可用,因为用户可采用 USB 存储设备的形式装载外部存储,并在某些情况下会从设备中将其移除。
它是全局可读的,因此此处保存的文件可能不受您控制地被读取。
当用户卸载您的应用时,只有在您通过 getExternalFilesDir() 将您的应用的文件保存在目录中时,系统才会从此处移除您的应用的文件。

对于无需访问限制以及您希望与其他应用共享或允许用户使用计算机访问的文件,外部存储是最佳位置。

注:在 Android N 之前,内部文件可以通过放宽文件系统权限让其他应用访问。而如今不再是这种情况。如果您希望让其他应用访问私有文件的内容,则您的应用可使用 FileProvider。 请参阅共享文件。

提示:尽管应用默认安装在内部存储中,但您可在您的清单文件中指定 android:installLocation 属性,这样您的应用便可安装在在外部存储中。当 APK 非常大且它们的外部存储空间大于内部存储时,用户更青睐这个选择。

获取外部存储的权限

要向外部存储写入信息,您必须在您的清单文件中请求 WRITE_EXTERNAL_STORAGE 权限。

将文件保存在内部存储中

在内部存储中保存文件时,您可以通过调用以下两种方法之一获取作为 File 的相应目录:

getFilesDir()
返回表示您的应用的内部目录的 File 。
getCacheDir()
返回表示您的应用临时缓存文件的内部目录的 File。 务必删除所有不再需要的文件并对在指定时间您使用的内存量实现合理大小限制,比如,1MB。 如果在系统即将耗尽存储,它会在不进行警告的情况下删除您的缓存文件。

要在这些目录之一中新建文件,您可以使用 File() 构造函数,传递指定您的内部存储目录的上述方法之一所提供的 File。例如:

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

或者,您可以调用 openFileOutput() 获取写入到内部目录中的文件的 FileOutputStream。例如,下面显示如何向文件写入一些文本:

String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;

try {
  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
  outputStream.write(string.getBytes());
  outputStream.close();
} catch (Exception e) {
  e.printStackTrace();
}

或者,如果您需要缓存某些文件,您应改用 createTempFile()。例如,以下方法从 URL 提取文件名并正在您的应用的内部缓存目录中以该名称创建文件:

public File getTempFile(Context context, String url) {
    File file;
    try {
        String fileName = Uri.parse(url).getLastPathSegment();
        file = File.createTempFile(fileName, null, context.getCacheDir());
    } catch (IOException e) {
        // Error while creating file
    }
    return file;
}

注:您的应用的内部存储设备目录由您的应用在 Android 文件系统特定位置中的软件包名称指定。从技术上讲,如果您将文件模式设置为可读,那么,另一应用也可以读取您的内部文件。 但是,此应用也需要知道您的应用的软件包名称和文件名。 其他应用无法浏览您的内部目录并且没有读写权限,除非您明确将文件设置为可读或可写。 只要您为内部存储上的文件使用 MODE_PRIVATE,其他应用便从不会访问它们。

将文件保存在外部存储中

由于外部存储可能不可用—比如,当用户已将存储装载到电脑或已移除提供外部存储的 SD 卡时—因此,在访问它之前,您应始终确认其容量。 您可以通过调用 getExternalStorageState() 查询外部存储状态。 如果返回的状态为 MEDIA_MOUNTED,那么您可以对您的文件进行读写。 例如,以下方法对于确定存储可用性非常有用:

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

尽管外部存储可被用户和其他应用进行修改,但您可在此处保存两类文件:

公共文件
应供其他应用和用户自由使用的文件。 当用户卸载您的应用时,用户应仍可以使用这些文件。

例如,您的应用拍摄的照片或其他已下载的文件。

私有文件
属于您的应用且在用户卸载您的应用时应予删除的文件。 尽管这些文件在技术上可被用户和其他应用访问(因为它们存储在外部存储中), 但它们实际上不向您的应用之外的用户提供任何输出值。 当用户卸载您的应用时,系统会删除应用外部私有目录中的所有文件。

例如,您的应用下载的其他资源或临时介质文件。

如果您要将公共文件保存在外部存储设备上,请使用 getExternalStoragePublicDirectory() 方法获取表示外部存储设备上相应目录的 File。 该方法使用指定您想要保存以便它们可以与其他公共文件在逻辑上组织在一起的文件类型的参数,比如 DIRECTORY_MUSIC 或 DIRECTORY_PICTURES。例如:

public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

如果您要保存您的应用专用文件,您可以通过调用 getExternalFilesDir() 并向其传递指示您想要的目录类型的名称,从而获取相应的目录。通过这种方法创建的各个目录将添加至封装您的应用的所有外部存储文件的父目录,当用户卸载您的应用时,系统会删除这些文件。

例如,您可以使用以下方法来创建个人相册的目录:

public File getAlbumStorageDir(Context context, String albumName) {
    // Get the directory for the app's private pictures directory.
    File file = new File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

如果没有适合您文件的预定义子目录名称,您可以改为调用 getExternalFilesDir() 并传递 null。这将返回外部存储上您的应用的专用目录的根目录。

切记,getExternalFilesDir() 在用户卸载您的应用时删除的目录内创建目录。如果您正保存的文件应在用户卸载您的应用后仍然可用—比如,当您的应用是照相机并且用户要保留照片时—您应改用 getExternalStoragePublicDirectory()。

无论您对于共享的文件使用 getExternalStoragePublicDirectory() 还是对您的应用专用文件使用 getExternalFilesDir(),您使用诸如 DIRECTORY_PICTURES 的 API 常数提供的目录名称非常重要。这些目录名称可确保系统正确处理文件。 例如,保存在 DIRECTORY_RINGTONES 中的文件由系统媒体扫描程序归类为铃声,而不是音乐。

查询可用空间

如果您事先知道您将保存的数据量,您可以查出是否有足够的可用空间,而无需调用 getFreeSpace() 或 getTotalSpace() 引起 IOException。这些方法分别提供目前的可用空间和存储卷中的总空间。 此信息也可用来避免填充存储卷以致超出特定阈值。

但是,系统并不保证您可以写入与 getFreeSpace() 指示的一样多的字节。如果返回的数字比您要保存的数据大小大出几 MB,或如果文件系统所占空间不到 90%,则可安全继续操作。否则,您可能不应写入存储。

注:保存您的文件之前,您无需检查可用空间量。 您可以尝试立刻写入文件,然后在 IOException 出现时将其捕获。 如果您不知道所需的确切空间量,您可能需要这样做。 例如,如果在保存文件之前通过将 PNG 图像转换成 JPEG 更改了文件的编码,您事先将不知道文件的大小。

删除文件

您应始终删除不再需要的文件。删除文件最直接的方法是让打开的文件参考自行调用 delete()。

myFile.delete();

如果文件保存在内部存储中,您还可以请求 Context 通过调用 deleteFile() 来定位和删除文件:

myContext.deleteFile(fileName);

注:当用户卸载您的应用时,Android 系统会删除以下各项:

  1. 您保存在内部存储中的所有文件
  2. 您使用 getExternalFilesDir() 保存在外部存储中的所有文件。

但是,您应手动删除使用 getCacheDir() 定期创建的所有缓存文件并且定期删除不再需要的其他文件。

常见的获取文件路径方法,对应的绝对路径

getCacheDir().getAbsolutePath():

/data/data/packagename/cache

getFilesDir().getAbsolutePath():

/data/data/packagename/files

以上为内存存储路径,以下为外部存储路径

getExternalCacheDir().getAbsolutePath():
可以作为外部缓存的路径,卸载app时,会自动删除文件

/storage/emulated/0/Android/data/packagename/cache

Environment.getExternalStorageDirectory().getAbsolutePath():

/storage/emulated/0

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()):

/storage/emulated/0/DCIM

getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath:

/storage/emulated/0/Android/data/packagename/files/Pictures
2019-02-12 18:57:20 weixin_42619856 阅读数 98
  • 快速入门Android开发 视频 教程 android studio

    这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 Android Studio基础使用方法 Android Studio创建项目 项目运行到模拟器 项目运行到真实手机 Android中常用控件 排查开发中的错误 Android中请求网络 常用Android开发命令 快速入门Gradle构建系统 项目实战:看美图 常用Android Studio使用技巧 项目签名打包 如何上架市场

    19197 人正在学习 去看看 任苹蜻

移动数据的存储方式之一就是文件存储,这里对其进行介绍。

使用特点与对象

特点:

不会对数据进行初始化处理,原封不动地讲数据存储到文件中

一般这几种数据可以用文件对数据进行存储:

  • 简单的文本数据
  • 二进制数据

使用方法

Android文件存储的方法代码和Java文件存储思路是一样的。但是Android文件存储创建文件和Java有所区别。这里Context类提供了一个openFileOutput方法指定存储数据的文件,如果指定文件不存在则会创建该文件。此方法接受两个参数:

  • 第一个参数:指定的文件名
  • 第二个参数:文件的操作方式,有两种可供选择:

MODE_APPEND 追加内容
MODE_PRIVATE 覆盖之前的内容

写入文件

public void save(String text){
    FileOutputStream out = null;
    BufferedWriter writer = null;
    try {
    //文件名为"data", 操作方式为追加
        out = openFileOutput("data", Context.MODE_APPEND);
        writer = new BufferedWriter(new OutputStreamWriter(out));
        writer.write(text);
    }catch (IOException e){
        e.printStackTrace();
    }finally {
        try {
            if(writer != null){
                writer.close();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

写出文件

这里将数据读取出来存放在Builder,然后将其返回

public String load(){
    FileInputStream in = null;
    BufferedReader reader = null;
    StringBuilder content = new StringBuilder();
    try {
    //指定读取文件"data"
        in = openFileInput("data");
        reader = new BufferedReader(new InputStreamReader(in));
        String line = "";
        while ((line = reader.readLine()) != null){
            content.append(line);  //将数据放在Builder
        }
    }catch (IOException e){
        e.printStackTrace();
    }finally {
        if (reader != null){
            try {
                reader.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
    return content.toString();
}

Android存储-文件存储数据(二)

博文 来自: zengruiyue

android文件存储

阅读数 119

android文件存储

博文 来自: longxiangxiang

android 文件存储

阅读数 51

没有更多推荐了,返回首页