zoukankan      html  css  js  c++  java
  • 【Android开发日记】之入门篇(七)——Android数据存储(上)

    在讲解Android的数据源组件——ContentProvider之前我觉得很有必要先弄清楚Android的数据结构。
    数据和程序是应用构成的两个核心要素,数据存储永远是应用开发中最重要的主题之一,也是开发平台必须提供的基础功能。不光是在Android平台上,在其他的平台上,数据的存储永远是不可缺少的一块。Android的数据存储是构建在Linux的文件系统上,它充分利用Linux的账号系统来限定应用对数据的访问,部署了一套安全和灵活并重的数据存储解决方案。Android的文件框架,以及各种数据存储手段,具体包括:Android的文件系统操作,设置文件的使用,数据库的使用,数据源组件的使用以及云端数据的存储

    一、Android的文件系统

    1. Android系统文件目录
      目录 内容
      system 系统目录,放置在Android运行所需的核心库
      data 应用目录,放置着运行在Android上的应用及其数据
      sdcard 扩展存储卡目录,用来存放共享的数据
      mnt 记录Android挂载的外部存储信息








    2. Android的应用数据存储机制
      在Android中,第三方应用及其数据,都存放在data目录下。其中,应用安装包会被存放到/data/app/目录下,每个安装包的文件名都形如:应用包名.apk,以避免重复。
      比如包名为com.test.sample的应用,其应用数据的目录为/data/data/com.test.sample/。对应的数据库文件存储在/data/data/com.test.sample/database/目录下,设置文件存储在/data/data/com.test.sample/shared_prefs/,自定义的应用数据文件存储在目录/data/data/com.test.sample/files/下,等等。
      不仅如此,Android还会为每个应用创建一个账号,只有通过本应用的账号才有权限去运行该应用的安装包文件,读写应用数据目录下的文件(当然root权限除外啊~),从而保证了该应用数据不会再被其他应用获取或破坏。
    3. Android的文件操作
      从应用数据目录下可以看出数据文件可以分成两类,一类是放置在扩展存储器中的文件,即/sdcard/目录下的文件,它们可以被各个应用共享;而另一类则是放在该应用数据目录下文件,它们仅能被各个应用独享,不能被其他应用读写。
      (1)扩展存储器中的文件读写方式跟标准的java文件处理无异。
            
      我们可以新建一个FileUtil的工具类来帮助我们处理文件的I/O操作,首先我们先判断SD卡的状态,看看SD卡是否可用,还有多少可用容量等。新建一个FileUtil的Class,加入方法
       1 // =================get SDCard information===================
       2     public static boolean isSdcardAvailable() {
       3         String status = Environment.getExternalStorageState();
       4         //Environment.MEDIA_MOUNTED表示SD卡正常挂载
       5         if (status.equals(Environment.MEDIA_MOUNTED)) {
       6             return true;
       7         }
       8         return false;
       9     }
      10 
      11     public static long getSDAllSizeKB() {
      12         //sd卡的位置
      13         File path = Environment.getExternalStorageDirectory();
      14         //StatFs获取的都是以block为单位的
      15         StatFs sf = new StatFs(path.getPath());
      16         // 得到单个block的大小
      17         long blockSize = sf.getBlockSize();
      18         // 获取所有数据块数
      19         long allBlocks = sf.getBlockCount();
      20         // 返回SD卡大小
      21         return (allBlocks * blockSize) / 1024; // KB
      22     }
      23 
      24     /**
      25      * free size for normal application
      26      * @return
      27      */
      28     public static long getSDAvalibleSizeKB() {
      29         File path = Environment.getExternalStorageDirectory();
      30         StatFs sf = new StatFs(path.getPath());
      31         long blockSize = sf.getBlockSize();
      32         long avaliableSize = sf.getAvailableBlocks();
      33         return (avaliableSize * blockSize) / 1024;// KB
      34     }

      Environment.getExternalStorageDirectory()表示获取扩展存储器的目录。(建议使用此方法动态获取,因为sdcard这个目录路径是可配置的)
      StatFs.getBlockSize在API18后变为StatFs.getBlockSizeLong,其他类似的getBlock方法也一样,关于StatFs,详情可以看这篇博文
      然后在activity中的button1加入事件

      case R.id.button1: {
                  Log.d("TEST", "sdcard?"+FileUtil.isSdcardAvailable());
                  Log.d("TEST", "全部容量"+(float)FileUtil.getSDAllSizeKB()/1024/1024);
                  Log.d("TEST", "可用容量"+(float)FileUtil.getSDAvalibleSizeKB()/1024/1024);
                  Toast.makeText(this, "status", Toast.LENGTH_SHORT).show();
                  break;
              }

      运行结果如下

      接下来我们来判断某个文件夹是否存在在SD卡中以及创建一个文件夹

      /**
           * @param director 文件夹名称
           * @return
           */
          public static boolean isFileExist(String director) {
              File file = new File(Environment.getExternalStorageDirectory()
                      + File.separator + director);
              return file.exists();
          }
      
          /**
           * create multiple director
           * @param path
           * @return
           */
          public static boolean createFile(String director) {
              if (isFileExist(director)) {
                  return true;
              } else {
                  File file = new File(Environment.getExternalStorageDirectory()
                          + File.separator + director);
                  if (!file.mkdirs()) {
                      return false;
                  }
                  return true;
              }
          }

      其中File.separator是表示分隔符,在不同操作系统下是不同的,如windows就是代表"/",而在Linux下却是代表""。所以介意使用File.separator来代替分隔符。File.mkdirs()表示创建一个文件夹,且可附带创建父目录,而mkdir()不行,详情的File大家可以查看官方文档,或者看看这篇博文
      然后在activity中的button2加入响应事件

      case R.id.button2: {
                  Log.d("TEST", "example文件夹存在?"+FileUtil.isFileExist("example"));
                  Log.d("TEST", "创建forexample文件夹"+FileUtil.createFile("forexample"));
                  Toast.makeText(this, "IsFile", Toast.LENGTH_SHORT).show();
                  break;
              }  

      运行后可以看到

      我们会发现在手机的sdcard目录下新建了一个forexample的文件夹

      最后我们来实现文件的读和写
      写:

      /**
           * 
           * @param director
           *            (you don't need to begin with
           *            Environment.getExternalStorageDirectory()+File.separator)
           * @param fileName
           * @param content
           * @param encoding
           *            (UTF-8...)
           * @param isAppend
           *            : Context.MODE_APPEND
           * @return
           */
          public static File writeToSDCardFile(String directory, String fileName,
                  String content, String encoding, boolean isAppend) {
              // mobile SD card path +path
              File file = null;
              OutputStream os = null;
              try {
                  if (!createFile(directory)) {
                      return file;
                  }
                  file = new File(Environment.getExternalStorageDirectory()
                          + File.separator + directory + File.separator + fileName);
                  os = new FileOutputStream(file, isAppend);
                  if (encoding.equals("")) {
                      os.write(content.getBytes());
                  } else {
                      os.write(content.getBytes(encoding));
                  }
                  os.flush();
              } catch (IOException e) {
                  Log.e("FileUtil", "writeToSDCardFile:" + e.getMessage());
              } finally {
                  try {
                      if (os != null) {
                          os.close();
                      }
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
              return file;
          }
      
          /**
           * write data from inputstream to SDCard
           */
          public File writeToSDCardFromInput(String directory, String fileName,
                  InputStream input) {
              File file = null;
              OutputStream os = null;
              try {
                  if (createFile(directory)) {
                      return file;
                  }
                  file = new File(Environment.getExternalStorageDirectory()
                          + File.separator + directory + File.separator + fileName);
                  os = new FileOutputStream(file);
                  byte[] data = new byte[bufferd];
                  int length = -1;
                  while ((length = input.read(data)) != -1) {
                      os.write(data, 0, length);
                  }
                  // clear cache
                  os.flush();
              } catch (Exception e) {
                  Log.e("FileUtil", "" + e.getMessage());
                  e.printStackTrace();
              } finally {
                  try {
                      os.close();
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
              return file;
          }

      从上面可以看到有两种写入的方法,一种是将字符串直接写入,另一种是将数据流写到文件中。还有一点要提的是file的默认目录就是sdcard的目录,所以开头不必每次都要加sdcard的目录路径。
      FileOutputStream(file, isAppend) 两个参数,左边是File文件,而右边是一个boolean值,为true时,数据将会接在原来文件的后面写入,而false是则会覆盖。
      读:

      public static String ReadFromSDCardFile(String directory,String fileName){
              String res=""; 
              File file = null;
              file = new File(Environment.getExternalStorageDirectory()
                      + File.separator + directory + File.separator + fileName);
              try {
                  FileInputStream fis = new FileInputStream(file);
                  int length = fis.available();
                  byte [] buffer = new byte[length]; 
                  fis.read(buffer);
      //将字节按照编码格式转成字符串 res
      = EncodingUtils.getString(buffer, "UTF-8"); fis.close(); return res; }catch (FileNotFoundException e) { // TODO Auto-generated catch block Log.d("TEST", "FileNotFound"); e.printStackTrace(); }catch (Exception e) { Log.d("TEST", "Can Not Open File"); e.printStackTrace(); } return null; }

      编码默认是UTF-8,若是想要改变的话,将其作为参数传入就行。
      Activity中在按钮中加入响应

      case R.id.button3: {
                  FileUtil.writeToSDCardFile("forexample", "test.txt",   
                          editText.getText().toString(), "UTF-8", true);
                  Toast.makeText(this, "WriteFile", Toast.LENGTH_SHORT).show();
                  break;
              } 
              case R.id.button4: {
                  textView.setText(FileUtil.ReadFromSDCardFile("forexample", "test.txt"));
                  Toast.makeText(this, "ReadFile", Toast.LENGTH_SHORT).show();
                  break;
              }

      在文字编辑框上写入“我是cpacm”,先点击writefile按钮,再点击ReadFile,得到运行结果

      同时在根目录下的forexample文件夹里会找到test.txt,里面有着“我是cpacm”的一行字。到此,文件的读写成功。
      (2)放在该应用数据目录下的文件读写
           存储在应用目录下的私有数据目录,通常不会通过File类的方式直接读写,而是利用一些封装过的类或函数来操作。一般可以通过Context.openFileOutput来执行。
          在Activity加入两个方法,分别为文件的读和写

          public void writeFile(String fileName,String writestr){ 
              try{ 
                      FileOutputStream fout =openFileOutput(fileName,MODE_PRIVATE); 
                      byte [] bytes = writestr.getBytes(); 
                      fout.write(bytes); 
                      fout.close(); 
                    } 
                      catch(Exception e){ 
                      e.printStackTrace(); 
                     } 
              } 
      
              //读数据
          public String readFile(String fileName){ 
            String res=""; 
            try{ 
                   FileInputStream fin = openFileInput(fileName); 
                   int length = fin.available(); 
                   byte [] buffer = new byte[length]; 
                   fin.read(buffer);     
                   res = EncodingUtils.getString(buffer, "UTF-8"); 
                   fin.close();     
               } 
               catch(Exception e){ 
                   e.printStackTrace(); 
               } 
               return res; 
          }

      同时在按钮的响应中加入

      case R.id.button5: {
                  writeFile("test2.txt",editText.getText().toString());
                  Toast.makeText(this, "WritePrivateFile", Toast.LENGTH_SHORT).show();
                  break;
              } 
              case R.id.button6: {
                  textView.setText(readFile("test2.txt"));
                  Toast.makeText(this, "ReadPrivateFile", Toast.LENGTH_SHORT).show();
                  break;
              }

      效果图跟上张一样。

      最后不要忘记在配置文件中声明权限

      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
     
     

    二、Android设置文件的使用

    用户在使用应用时,常常会有一些个人偏好。为了满足不同用户的需求,应用通常会提供对应的设置项(Preference),让用户根据自己的喜好选择。这些设置信息会存储在本地并进行结构化地展示,使用户可以编辑。

    1. 设置文件的存储和使用

      Android应用的设置数据,可以通过android.content.SharedPreferences类来表示。它提供了一组数据读取的接口,可以从设置文件中读取给定键值的整形数,布尔型数等数据。
      首先是获取SharedPreferences
      private SharedPreferences userInfo;
              //在界面组件或服务组件中调用,构造应用默认的设置文件,默认文件名字为_preferences.xml
              //userInfo = PreferenceManager.getDefaultSharedPreferences(this);  
              //或获取指定名字的SharedPreferences对象  参数分别为存储的文件名和存储模式。
              userInfo = getSharedPreferences("preferences", Activity.MODE_PRIVATE); 
              
              //读取数据,如果无法找到则会使用默认值
              String username = userInfo.getString("name", "未定义姓名");  
              String msg = userInfo.getString("msg", "未定义信息");
              //显示文本
              textView.setText(username+","+msg);

      两种获取方式,默认或者指定一个文件
      接下来加入响应按钮

              case R.id.button7: {
                  //获得SharedPreferences的编辑器
                  SharedPreferences.Editor editor = userInfo.edit();
                  //将信息存入相应的键值中
                  editor.putString("name", editText.getText().toString()).commit();
                  Toast.makeText(this, "SetName", Toast.LENGTH_SHORT).show();
                  break;
              } 
              case R.id.button8: {
                  //获得SharedPreferences的编辑器
                  SharedPreferences.Editor editor = userInfo.edit();
                  //将信息存入相应的键值中ss
                  editor.putString("msg", editText.getText().toString()).commit();
                  Toast.makeText(this, "SetMessage", Toast.LENGTH_SHORT).show();
                  break;
              } 
              case R.id.button9: {
      //获得SharedPreferences文件 userInfo
      = getSharedPreferences("preferences", Activity.MODE_PRIVATE); String username = userInfo.getString("name", "未定义姓名"); String msg = userInfo.getString("msg", "未定义信息"); textView.setText(username+","+msg); Toast.makeText(this, "ShowMsg", Toast.LENGTH_SHORT).show(); break; } case R.id.button10: {
      //输出XML文件 textView.setText(print()); Toast.makeText(
      this, "ShowXML", Toast.LENGTH_SHORT).show(); break; }

      按钮7,8可以设置信息,按钮9则从SharedPreferences文件中读取信息并显示在文字框中。按钮10会显示这个XML文件中的所有信息。


      访问其他应用中的Preference(在SecondApp中访问FirstApp的数据),前提条件是:FirstApp的preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。

      如:在<package name>为com.first.app的应用使用下面语句创建了preference("first_app_perferences")。

      Java代码
      getSharedPreferences("first_app_perferences", Context.MODE_WORLD_READABLE);  

      在SecondApp中要访问FirstApp应用中的preference,首先需要创建FirstApp应用的Context,然后通过Context 访问preference ,访问preference时会在应用所在包下的shared_prefs目录找到preference

      Context firstAppContext = createPackageContext("com.first.app", Context.CONTEXT_IGNORE_SECURITY);   
      SharedPreferences sharedPreferences = firstAppContext.getSharedPreferences("first_app_perferences",  Context.MODE_WORLD_READABLE);   
      String name = sharedPreferences.getString("name", "");  
      int age = sharedPreferences.getInt("age", 0); 

      如果不通过创建Context访问FirstApp应用的preference,可以以读取xml文件方式直接访问FirstApp应用的preference对应的xml文件,

      如: 
      File xmlFile = new File(“/data/data/<package name>/shared_prefs/first_app_perferences.xml”);//<package name>应替换成应用的包名: com.first.app

       

    2. 设置界面组件
      有一类特殊的Preference对象:android.preference.PreferenceGroup。它是容器型的Preference对象,负责管理一组相关联的Preference对象。设置项编辑的界面组件,通常派生自android.preference.PreferenceActivity类。它可以将一个定制好的设置树转换成对应的控件呈现出来。
      public class PreferencesDemo extends PreferenceActivity{
           @Override
           public void onCreate(Bundle savadInstanceState){
               super.onCreate(savadInstanceState);
               this.addPreferencesFromResource(R.xml.preference);
           }
      }

      其中,R.xml.preference表示描述设置信息的资源文件。放在XML资源目录下。
      详细可以参考Android的配置界面PreferenceActivity

     
      1 public class MainActivity extends Activity implements OnClickListener {
      2     
      3      /** 存储后的文件路径:/data/data/<package name>/shares_prefs + 文件名.xml */ 
      4     public static final String PATH = "/data/data/com.example.datademo/shared_prefs/preferences.xml";
      5     private SharedPreferences userInfo;
      6 
      7     private Button button1;
      8     private Button button2;
      9     private Button button3;
     10     private Button button4;
     11     private Button button5;
     12     private Button button6;
     13     private Button button7;
     14     private Button button8;
     15     private Button button9;
     16     private Button button10;
     17     private TextView textView;
     18     private EditText editText;
     19 
     20     @Override
     21     protected void onCreate(Bundle savedInstanceState) {
     22         super.onCreate(savedInstanceState);
     23         setContentView(R.layout.activity_main);
     24 
     25         // 获得界面的控件
     26         textView = (TextView) findViewById(R.id.textView1);
     27         editText = (EditText) findViewById(R.id.editText1);
     28         button1 = (Button) findViewById(R.id.button1);
     29         button1.setOnClickListener(this);
     30         button2 = (Button) findViewById(R.id.button2);
     31         button2.setOnClickListener(this);
     32         button3 = (Button) findViewById(R.id.button3);
     33         button3.setOnClickListener(this);
     34         button4 = (Button) findViewById(R.id.button4);
     35         button4.setOnClickListener(this);
     36         button5 = (Button) findViewById(R.id.button5);
     37         button5.setOnClickListener(this);
     38         button6 = (Button) findViewById(R.id.button6);
     39         button6.setOnClickListener(this);
     40         button7 = (Button) findViewById(R.id.button7);
     41         button7.setOnClickListener(this);
     42         button8 = (Button) findViewById(R.id.button8);
     43         button8.setOnClickListener(this);
     44         button9 = (Button) findViewById(R.id.button9);
     45         button9.setOnClickListener(this);
     46         button10 = (Button) findViewById(R.id.button10);
     47         button10.setOnClickListener(this);
     48         
     49         //在界面组件或服务组件中调用,构造应用默认的设置文件,默认文件名字为_preferences.xml
     50         //userInfo = PreferenceManager.getDefaultSharedPreferences(this);  
     51         //或获取指定名字的SharedPreferences对象  参数分别为存储的文件名和存储模式。
     52         userInfo = getSharedPreferences("preferences.xml", Activity.MODE_PRIVATE); 
     53         
     54         //读取数据,如果无法找到则会使用默认值
     55         String username = userInfo.getString("name", "未定义姓名");  
     56         String msg = userInfo.getString("msg", "未定义信息");
     57         //显示文本
     58         textView.setText(username+","+msg);
     59     }
     60 
     61     @Override
     62     public void onClick(View v) {
     63         // TODO Auto-generated method stub
     64         switch (v.getId()) {
     65         case R.id.button1: {
     66             Log.d("TEST", "sdcard?"+FileUtil.isSdcardAvailable());
     67             Log.d("TEST", "全部容量"+(float)FileUtil.getSDAllSizeKB()/1024/1024);
     68             Log.d("TEST", "可用容量"+(float)FileUtil.getSDAvalibleSizeKB()/1024/1024);
     69             Toast.makeText(this, "status", Toast.LENGTH_SHORT).show();
     70             break;
     71         }
     72         case R.id.button2: {
     73             Log.d("TEST", "example文件夹存在?"+FileUtil.isFileExist("example"));
     74             Log.d("TEST", "创建forexample文件夹"+FileUtil.createFile("forexample"));
     75             Toast.makeText(this, "IsFile", Toast.LENGTH_SHORT).show();
     76             break;
     77         }  
     78         case R.id.button3: {
     79             FileUtil.writeToSDCardFile("forexample", "test.txt",   
     80                     editText.getText().toString(), "UTF-8", true);
     81             Toast.makeText(this, "WriteFile", Toast.LENGTH_SHORT).show();
     82             break;
     83         } 
     84         case R.id.button4: {
     85             textView.setText(FileUtil.ReadFromSDCardFile("forexample", "test.txt"));
     86             Toast.makeText(this, "ReadFile", Toast.LENGTH_SHORT).show();
     87             break;
     88         } 
     89         case R.id.button5: {
     90             writeFile("test2.txt",editText.getText().toString());
     91             Toast.makeText(this, "WritePrivateFile", Toast.LENGTH_SHORT).show();
     92             break;
     93         } 
     94         case R.id.button6: {
     95             textView.setText(readFile("test2.txt"));
     96             Toast.makeText(this, "ReadPrivateFile", Toast.LENGTH_SHORT).show();
     97             break;
     98         } 
     99         case R.id.button7: {
    100             //获得SharedPreferences的编辑器
    101             SharedPreferences.Editor editor = userInfo.edit();
    102             //将信息存入相应的键值中
    103             editor.putString("name", editText.getText().toString()).commit();
    104             Toast.makeText(this, "SetName", Toast.LENGTH_SHORT).show();
    105             break;
    106         } 
    107         case R.id.button8: {
    108             //获得SharedPreferences的编辑器
    109             SharedPreferences.Editor editor = userInfo.edit();
    110             //将信息存入相应的键值中ss
    111             editor.putString("msg", editText.getText().toString()).commit();
    112             Toast.makeText(this, "SetMessage", Toast.LENGTH_SHORT).show();
    113             break;
    114         } 
    115         case R.id.button9: {
    116             userInfo = getSharedPreferences("preferences.xml", Activity.MODE_PRIVATE);
    117             String username = userInfo.getString("name", "未定义姓名");  
    118             String msg = userInfo.getString("msg", "未定义信息");
    119             textView.setText(username+","+msg);
    120             Toast.makeText(this, "ShowMsg", Toast.LENGTH_SHORT).show();
    121             break;
    122         } 
    123         case R.id.button10: {
    124             textView.setText(print());
    125             Toast.makeText(this, "ShowXML", Toast.LENGTH_SHORT).show();
    126             break;
    127         } 
    128         }
    129     }
    130     
    131     public void writeFile(String fileName,String writestr){ 
    132         try{ 
    133                 FileOutputStream fout =openFileOutput(fileName,MODE_PRIVATE); 
    134                 byte [] bytes = writestr.getBytes(); 
    135                 fout.write(bytes); 
    136                 fout.close(); 
    137               } 
    138                 catch(Exception e){ 
    139                 e.printStackTrace(); 
    140                } 
    141         } 
    142 
    143         //读数据
    144     public String readFile(String fileName){ 
    145       String res=""; 
    146       try{ 
    147              FileInputStream fin = openFileInput(fileName); 
    148              int length = fin.available(); 
    149              byte [] buffer = new byte[length]; 
    150              fin.read(buffer);     
    151              res = EncodingUtils.getString(buffer, "UTF-8"); 
    152              fin.close();     
    153          } 
    154          catch(Exception e){ 
    155              e.printStackTrace(); 
    156          } 
    157          return res; 
    158     }
    159     
    160     private String print() {  
    161         StringBuffer buff = new StringBuffer();  
    162         try {  
    163             BufferedReader reader = new BufferedReader(new InputStreamReader(  
    164                     new FileInputStream(PATH)));  
    165             String str;  
    166             while ((str = reader.readLine()) != null) {  
    167                 buff.append(str + "/n");  
    168             }  
    169         } catch (Exception e) {  
    170             e.printStackTrace();  
    171         }  
    172         return buff.toString();  
    173     }
    174 
    175 }
    View Code
      1 package com.example.datademo;
      2 
      3 import java.io.File;
      4 import java.io.FileInputStream;
      5 import java.io.FileNotFoundException;
      6 import java.io.FileOutputStream;
      7 import java.io.IOException;
      8 import java.io.InputStream;
      9 import java.io.OutputStream;
     10 
     11 import org.apache.http.util.EncodingUtils;
     12 
     13 import android.os.Environment;
     14 import android.os.StatFs;
     15 import android.util.Log;
     16 
     17 public class FileUtil {
     18     private static int bufferd = 1024;
     19 
     20     private FileUtil() {
     21     }
     22 
     23     /*
     24      * <!-- 在SDCard中创建与删除文件权限 --> <uses-permission
     25      * android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!--
     26      * 往SDCard写入数据权限 --> <uses-permission
     27      * android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     28      */
     29 
     30     // =================get SDCard information===================
     31     public static boolean isSdcardAvailable() {
     32         String status = Environment.getExternalStorageState();
     33         //Environment.MEDIA_MOUNTED表示SD卡正常挂载
     34         //sd卡   http://blog.csdn.net/yuzhiboyi/article/details/8645730
     35         if (status.equals(Environment.MEDIA_MOUNTED)) {
     36             return true;
     37         }
     38         return false;
     39     }
     40 
     41     public static long getSDAllSizeKB() {
     42         // get path of sdcard
     43         File path = Environment.getExternalStorageDirectory();
     44         //StatFs获取的都是以block为单位的   http://blog.csdn.net/pang3510726681/article/details/6969557
     45         StatFs sf = new StatFs(path.getPath());
     46         // get single block size(Byte)
     47         long blockSize = sf.getBlockSize();
     48         // 获取所有数据块数
     49         long allBlocks = sf.getBlockCount();
     50         // 返回SD卡大小
     51         return (allBlocks * blockSize) / 1024; // KB
     52     }
     53 
     54     /**
     55      * free size for normal application
     56      * 
     57      * @return
     58      */
     59     public static long getSDAvalibleSizeKB() {
     60         File path = Environment.getExternalStorageDirectory();
     61         StatFs sf = new StatFs(path.getPath());
     62         long blockSize = sf.getBlockSize();
     63         long avaliableSize = sf.getAvailableBlocks();
     64         return (avaliableSize * blockSize) / 1024;// KB
     65     }
     66 
     67     // =====================File Operation==========================
     68     /**
     69      * @param director 文件夹名称
     70      * @return
     71      */
     72     public static boolean isFileExist(String director) {
     73         File file = new File(Environment.getExternalStorageDirectory()
     74                 + File.separator + director);
     75         return file.exists();
     76     }
     77 
     78     /**
     79      * create multiple director
     80      * 
     81      * @param path
     82      * @return
     83      */
     84     public static boolean createFile(String director) {
     85         if (isFileExist(director)) {
     86             return true;
     87         } else {
     88             File file = new File(Environment.getExternalStorageDirectory()
     89                     + File.separator + director);
     90             if (!file.mkdirs()) {
     91                 return false;
     92             }
     93             return true;
     94         }
     95     }
     96 
     97     public static File writeToSDCardFile(String directory, String fileName,
     98             String content, boolean isAppend) {
     99         return writeToSDCardFile(directory, fileName, content, "", isAppend);
    100     }
    101 
    102     /**
    103      * 
    104      * @param director
    105      *            (you don't need to begin with
    106      *            Environment.getExternalStorageDirectory()+File.separator)
    107      * @param fileName
    108      * @param content
    109      * @param encoding
    110      *            (UTF-8...)
    111      * @param isAppend
    112      *            : Context.MODE_APPEND
    113      * @return
    114      */
    115     public static File writeToSDCardFile(String directory, String fileName,
    116             String content, String encoding, boolean isAppend) {
    117         // mobile SD card path +path
    118         File file = null;
    119         OutputStream os = null;
    120         try {
    121             if (!createFile(directory)) {
    122                 return file;
    123             }
    124             file = new File(Environment.getExternalStorageDirectory()
    125                     + File.separator + directory + File.separator + fileName);
    126             os = new FileOutputStream(file, isAppend);
    127             if (encoding.equals("")) {
    128                 os.write(content.getBytes());
    129             } else {
    130                 os.write(content.getBytes(encoding));
    131             }
    132             os.flush();
    133         } catch (IOException e) {
    134             Log.e("FileUtil", "writeToSDCardFile:" + e.getMessage());
    135         } finally {
    136             try {
    137                 if (os != null) {
    138                     os.close();
    139                 }
    140             } catch (IOException e) {
    141                 e.printStackTrace();
    142             }
    143         }
    144         return file;
    145     }
    146 
    147     /**
    148      * write data from inputstream to SDCard
    149      */
    150     public static File writeToSDCardFromInput(String directory, String fileName,
    151             InputStream input) {
    152         File file = null;
    153         OutputStream os = null;
    154         try {
    155             if (createFile(directory)) {
    156                 return file;
    157             }
    158             file = new File(Environment.getExternalStorageDirectory()
    159                     + File.separator + directory + File.separator + fileName);
    160             os = new FileOutputStream(file);
    161             byte[] data = new byte[bufferd];
    162             int length = -1;
    163             while ((length = input.read(data)) != -1) {
    164                 os.write(data, 0, length);
    165             }
    166             // clear cache
    167             os.flush();
    168         } catch (Exception e) {
    169             Log.e("FileUtil", "" + e.getMessage());
    170             e.printStackTrace();
    171         } finally {
    172             try {
    173                 os.close();
    174             } catch (Exception e) {
    175                 e.printStackTrace();
    176             }
    177         }
    178         return file;
    179     }
    180     
    181     public static String ReadFromSDCardFile(String directory,String fileName){
    182         String res=""; 
    183         File file = null;
    184         file = new File(Environment.getExternalStorageDirectory()
    185                 + File.separator + directory + File.separator + fileName);
    186         try {
    187             FileInputStream fis = new FileInputStream(file);
    188             int length = fis.available();
    189             byte [] buffer = new byte[length]; 
    190             fis.read(buffer);
    191             res = EncodingUtils.getString(buffer, "UTF-8");
    192             fis.close();
    193             return res;
    194         }catch (FileNotFoundException  e) {
    195             // TODO Auto-generated catch block
    196             Log.d("TEST", "FileNotFound");
    197             e.printStackTrace();
    198         }catch (Exception  e) {
    199             Log.d("TEST", "Can Not Open File");
    200             e.printStackTrace();
    201         }
    202         return null;     
    203     }
    204 }
    View Code

    资源下载:DataDemo

    参考文章:(1)Android中的SharedPreferences存储数据方式  http://blog.csdn.net/zuolongsnail/article/details/6556703
             (2)Android - 文件操作 小结   http://www.open-open.com/lib/view/open1330957864280.html
    限于篇幅,这篇文章就到此结束,这篇主要讲了如何在Android中读写文件,包括SDCard中和应用内部的文件。以及如何使用设置文件。在下一篇我会讲解Android内部自带的数据库使用及操作。

    ========================================

    作者:cpacm
    出处:(http://www.cpacm.net/2015/03/22/Android开发日记(五)——Android数据存储(上)/

     

  • 相关阅读:
    Scrapy爬虫框架
    python Re库的介绍
    正则表达式,regular expression, regex, RE
    信息标记的三种形式
    python Beautiful Soup库入门
    python requests第三方库详解
    递归算法
    枚举算法
    MySQL CONCAT()与GROUP_CONCAT()的使用
    关于日期函数查询总结
  • 原文地址:https://www.cnblogs.com/cpacm/p/3919352.html
Copyright © 2011-2022 走看看