• Android Rom分区 与 SD卡读写


    1、Rom分区

      在Android中,对数据的保护是很严密的。除了放在SD卡中的数据,一个应用所拥有的数据库、文件等内容都是不允许其他应用直接访问的,这一部分数据都是在/data/data里面。

      这里所说的SD卡是逻辑上的SD卡,比如我现在用的galaxy s4 的Rom是16g,Android系统会把这16g分成两个部分,一个是系统和应用程序数据区,另一个就是虚拟的SD卡,可以称它为内置SD卡。

      我们平时外插进手机的是TF卡,简称Micro SD卡,具体的可以参考百度。  

      三星手机默认的内置SD卡的挂载点是/storage/emulated/0.

      android是基于linux的,linux里的要使用存储设备就要先把它挂载到到linux的目录树上(以/为根),android上一般是挂载到/storage/emulated/这个目录对应的目录或者/storage对应目录里的,假如你可以放两张内存卡,那些就可能是分别挂载到 /storage/emulated/0/  和/storage/emulated/1/ 这样的目录。。而你得到/storage/emulated/0/是你SD卡的真正目录。。不是引用路径。以前你可能会得到的是/sdcard 这样的路径。那个才是一个链接(你所说的引用),链接到你SD直正的挂载目录/storage/emulated/0 。。所以当你访问两个路径时得到的内容是一样的。

    2、获取内置和外置SD卡路径

      测试环境  三星note3

      需要权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
     
    import android.os.Bundle;
    import android.os.Environment;
    import android.app.Activity;
    import android.view.Menu;
     
    public class MainActivity extends Activity {
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
     
            StringBuilder log = new StringBuilder();
            String inPath = getInnerSDCardPath();
            log.append("内置SD卡路径:" + inPath + "
    ");
             
            List<string> extPaths = getExtSDCardPath();
            for (String path : extPaths) {
                log.append("外置SD卡路径:" + path + "
    ");
            }
            System.out.println(log.toString());
        }
         
        /**
         * 获取内置SD卡路径
         * @return
         */
        public String getInnerSDCardPath() {  
            return Environment.getExternalStorageDirectory().getPath();  
        }
     
        /**
         * 获取外置SD卡路径
         * @return  应该就一条记录或空
         */
        public List<string> getExtSDCardPath()
        {
            List<string> lResult = new ArrayList<string>();
            try {
                Runtime rt = Runtime.getRuntime();
                Process proc = rt.exec("mount");
                InputStream is = proc.getInputStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line;
                while ((line = br.readLine()) != null) {
                    if (line.contains("extSdCard"))
                    {
                        String [] arr = line.split(" ");
                        String path = arr[1];
                        File file = new File(path);
                        if (file.isDirectory())
                        {
                            lResult.add(path);
                        }
                    }
                }
                isr.close();
            } catch (Exception e) {
            }
            return lResult;
        }
     
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }
     
    }

    打印结果:

    1. 插入一张外置SD卡后

     
    内置SD卡路径:/storage/emulated/0
    外置SD卡路径:/storage/extSdCard

    2. 取出外置SD卡后

    内置SD卡路径:/storage/emulated/0

     

    sdcard:

            在现在的android手机中,由于有从rom划分出来的内置存储和可以插sd卡两个控件,所以就产生了/mnt/sdcard和/mnt/sdcard2.在按揉的提供的模拟器中是没有sdcard2这个目录的,原因在于模拟器并没有将rom划分出内部存储。

             通过代码,获取内部空间的时候,发现不同的手机获取的方式各有不同:比如说我的华为手机,获取手机内部存储的时候,实际上获取的是/data分区的空间,而在有的手机获取的却是rom划分后剩余的空间(及被我们叫做内部存储的空间)

    而获取sdcard空间的时候分两种情况:

      1、手机没有插sd卡的时候,这时获取的总SD卡空间为rom被划分后剩余的内部存储空间

      2、手机插上sd卡的时候,这时获取的总SD卡空间为外部sd卡的空间

    3、SD卡读写

    import java.io.FileInputStream; 
    import java.io.FileOutputStream; 
    import java.io.InputStream; 
    import org.apache.http.util.EncodingUtils; 
    import android.app.Activity; 
      
    public class FileAccess { 
      
        /**
         * 一、私有文件夹下的文件存取(/data/data/包名/files)
         * 
         * @param fileName
         * @param message
         */
        public void writeFileData(String fileName, String message) { 
            try { 
                FileOutputStream fout = openFileOutput(fileName, MODE_PRIVATE); 
                byte[] bytes = message.getBytes(); 
                fout.write(bytes); 
                fout.close(); 
            } catch (Exception e) { 
                e.printStackTrace(); 
            } 
        } 
      
        /**
         * //读文件在./data/data/包名/files/下面
         * 
         * @param fileName
         * @return
         */
        public String readFileData(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; 
        } 
      
        /**
         * 写, 读sdcard目录上的文件,要用FileOutputStream, 不能用openFileOutput
         * 不同点:openFileOutput是在raw里编译过的,FileOutputStream是任何文件都可以
         * @param fileName
         * @param message
         */
        // 写在/mnt/sdcard/目录下面的文件 
        public void writeFileSdcard(String fileName, String message) { 
            try { 
                // FileOutputStream fout = openFileOutput(fileName, MODE_PRIVATE); 
                FileOutputStream fout = new FileOutputStream(fileName); 
                byte[] bytes = message.getBytes(); 
                fout.write(bytes); 
                fout.close(); 
            } 
            catch (Exception e) { 
                e.printStackTrace(); 
            } 
        } 
        // 读在/mnt/sdcard/目录下面的文件 
        public String readFileSdcard(String fileName) { 
            String res = ""; 
            try { 
                FileInputStream fin = new FileInputStream(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; 
        } 
      
        /**
         * 二、从resource中的raw文件夹中获取文件并读取数据(资源文件只能读不能写)
         * 
         * @param fileInRaw
         * @return
         */
        public String readFromRaw(int fileInRaw) { 
            String res = ""; 
            try { 
                InputStream in = getResources().openRawResource(fileInRaw); 
                int length = in.available(); 
                byte[] buffer = new byte[length]; 
                in.read(buffer); 
                res = EncodingUtils.getString(buffer, "GBK"); 
                // res = new String(buffer,"GBK"); 
                in.close(); 
            } catch (Exception e) { 
                e.printStackTrace(); 
            } 
            return res; 
        } 
      
        /**
         * 三、从asset中获取文件并读取数据(资源文件只能读不能写)
         * 
         * @param fileName
         * @return
         */
        public String readFromAsset(String fileName) { 
            String res = ""; 
            try { 
                InputStream in = getResources().getAssets().open(fileName); 
                int length = in.available(); 
                byte[] buffer = new byte[length]; 
                in.read(buffer); 
                res = EncodingUtils.getString(buffer, "UTF-8"); 
            } catch (Exception e) { 
                e.printStackTrace(); 
            } 
            return res; 
        } 
      
      
      
    }
     
  • 相关阅读:
    分支与合并@基础
    创业者那些鲜为人知的事情
    centos7.5+nginx+php急速配置
    通过webhost扩展方式初始化EFCore数据库
    AspNetCore架构图
    Linux就该这样学--之常用linux命令及bash基础
    使用gitlab构建基于docker的持续集成(三)
    使用gitlab构建基于docker的持续集成(二)
    使用gitlab构建基于docker的持续集成(一)
    使用docker-compose配置mysql数据库并且初始化用户
  • 原文地址:https://www.cnblogs.com/maydow/p/4605536.html
Copyright © 2020-2023  润新知