展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 系统应用 > 6.1 数据存储与访问之——文件存储读写

6.1 数据存储与访问之——文件存储读写

本节引言: 看到这个题目,估计不少读者会先冒出一个问题:前面的Fragment部分写完了吗?答案是,还没有。原因也不复杂,主要是想把例子打磨得更合适,多少还需要一点时间。为了把整体进度往前推,这套教程最近就换了个思路来写——有点像“多线程”并发推进,几部分内容同步展开,这样效率确实会高一些。写到现在

本文目录

    本节引言:

    看到这个题目,估计不少读者会先冒出一个问题:前面的Fragment部分写完了吗?答案是,还没有。原因也不复杂,主要是想把例子打磨得更合适,多少还需要一点时间。为了把整体进度往前推,这套教程最近就换了个思路来写——有点像“多线程”并发推进,几部分内容同步展开,这样效率确实会高一些。写到现在,刚好完成了60篇,距离整套入门教程全部收尾,其实还有不短的路要走。前面也提到过,希望能在一个半到两个月内把这套教程完成,而今天已经是9月1日,节奏确实得再提一提了。闲话先收一收,这一节要讲的是Android数据存储与访问方式中的一个重点内容:文件存储与读写。当然,除了文件这种方式,数据也可以放到SharedPreference、数据库,或者Application中,这些内容后面都会陆续展开。接下来,就正式进入本节内容。

    1.Android文件的操作模式

    学过Ja va的同学都知道,我们新建文件,然后就可以写入数据了,但是Android却不一样,因为Android是 基于Linux的,我们在读写文件的时候,还需加上文件的操作模式,Android中的操作模式如下:

    2.文件的相关操作方法

    3.文件读写的实现

    Android中的文件读写和Ja va中的文件I/O相同,流程也很简单,下面我们来写个简单的示例:

    实现效果图:

    PS:这里用的是模拟器,因为笔者的N5并没有root,看不到文件的存储目录,下面我们打开DDMS 的File Exploer可以看到,在data/data/<包名>/file中有我们写入的文件:

    我们可以点击右上角的响应图标将文件导入到电脑中,并且打开验证写入的内容:

    代码实现:

    首先是布局文件:main_activity.xml

    
    
    
    
    
    
    

    然后我们来写一个文件协助类:FileHelper.ja va

    /**
     * Created by Jay on 2015/9/1 0001.
     */
    public class FileHelper {
    private Context mContext;
    public FileHelper() {
        }
    public FileHelper(Context mContext) {
            super();
            this.mContext = mContext;
        }
    /*
        * 这里定义的是一个文件保存的方法,写入到文件中,所以是输出流
        * */
        public void sa ve(String filename, String filecontent) throws Exception {
            //这里我们使用私有模式,创建出来的文件只能被本应用访问,还会覆盖原文件哦
            FileOutputStream output = mContext.openFileOutput(filename, Context.MODE_PRIVATE);
            output.write(filecontent.getBytes());  //将String字符串以字节流的形式写入到输出流中
            output.close();         //关闭输出流
        }
    /*
        * 这里定义的是文件读取的方法
        * */
        public String read(String filename) throws IOException {
            //打开文件输入流
            FileInputStream input = mContext.openFileInput(filename);
            byte[] temp = new byte[1024];
            StringBuilder sb = new StringBuilder("");
            int len = 0;
            //读取文件内容:
            while ((len = input.read(temp)) > 0) {
                sb.append(new String(temp, 0, len));
            }
            //关闭输入流
            input.close();
            return sb.toString();
        }
    }

    最后是MainActivity.ja va,我们在这里完成相关操作:

    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private EditText editname;
        private EditText editdetail;
        private Button btnsa ve;
        private Button btnclean;
        private Button btnread;
        private Context mContext;
    @Override
        protected void onCreate(Bundle sa vedInstanceState) {
            super.onCreate(sa vedInstanceState);
            setContentView(R.layout.activity_main);
            mContext = getApplicationContext();
            bindViews();
        }
    private void bindViews() {
            editdetail = (EditText) findViewById(R.id.editdetail);
            editname = (EditText) findViewById(R.id.editname);
            btnclean = (Button) findViewById(R.id.btnclean);
            btnsa ve = (Button) findViewById(R.id.btnsa ve);
            btnread = (Button) findViewById(R.id.btnread);
    btnclean.setOnClickListener(this);
            btnsa ve.setOnClickListener(this);
            btnread.setOnClickListener(this);
        }
    @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btnclean:
                    editdetail.setText("");
                    editname.setText("");
                    break;
                case R.id.btnsa ve:
                    FileHelper fHelper = new FileHelper(mContext);
                    String filename = editname.getText().toString();
                    String filedetail = editdetail.getText().toString();
                    try {
                        fHelper.sa ve(filename, filedetail);
                        Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();
                    } catch (Exception e) {
                        e.printStackTrace();
                        Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();
                    }
                    break;
                case R.id.btnread:
                    String detail = "";
                    FileHelper fHelper2 = new FileHelper(getApplicationContext());
                    try {
                        String fname = editname.getText().toString();
                        detail = fHelper2.read(fname);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }

    4.读取SD卡上的文件

    读取流程图:

    代码示例:

    运行效果图:

    同样打开DDMS的File Explorer,在旧版本的系统上我们可以直接在mmtsdcard上找到,但是新版本 的就可能需要我们自己找找了,首先我们来到这个路径下:

    点开sdcard,但是没东西,我们继续找唠叨后面这个/storage/emulated/legacy下找:

    好吧,他又跳到别的地方去了,我们继续找/storage/shell/emilated/0

    果然找到了,我们在SD卡里生成的test.txt!导出到电脑看下里面的内容:

    嘿嘿,果然读写SD卡成功~接下来我们来看下代码是怎么写的:

    代码实现:

    main_activity.xml:

    
    
    
    
    
    

    接着我们来写一个SD操作类: SDFileHelper.ja va

    /**
     * Created by Jay on 2015/9/1 0001.
     */
    public class SDFileHelper {
    private Context context;
    public SDFileHelper() {
        }
    public SDFileHelper(Context context) {
            super();
            this.context = context;
        }
    //往SD卡写入文件的方法
        public void sa vaFileToSD(String filename, String filecontent) throws Exception {
            //如果手机已插入sd卡,且app具有读写sd卡的权限
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
                //这里就不要用openFileOutput了,那个是往手机内存中写数据的
                FileOutputStream output = new FileOutputStream(filename);
                output.write(filecontent.getBytes());
                //将String字符串以字节流的形式写入到输出流中
                output.close();
                //关闭输出流
            } else Toast.makeText(context, "SD卡不存在或者不可读写", Toast.LENGTH_SHORT).show();
        }
    //读取SD卡中文件的方法
        //定义读取文件的方法:
        public String readFromSD(String filename) throws IOException {
            StringBuilder sb = new StringBuilder("");
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
                //打开文件输入流
                FileInputStream input = new FileInputStream(filename);
                byte[] temp = new byte[1024];
    int len = 0;
                //读取文件内容:
                while ((len = input.read(temp)) > 0) {
                    sb.append(new String(temp, 0, len));
                }
                //关闭输入流
                input.close();
            }
            return sb.toString();
        }
    }

    接着MainActivity.ja va实现相关逻辑:

    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private EditText editname;
        private EditText editdetail;
        private Button btnsa ve;
        private Button btnclean;
        private Button btnread;
        private Context mContext;
    @Override
        protected void onCreate(Bundle sa vedInstanceState) {
            super.onCreate(sa vedInstanceState);
            setContentView(R.layout.activity_main);
            mContext = getApplicationContext();
            bindViews();
        }
    private void bindViews() {
            editname = (EditText) findViewById(R.id.edittitle);
            editdetail = (EditText) findViewById(R.id.editdetail);
            btnsa ve = (Button) findViewById(R.id.btnsa ve);
            btnclean = (Button) findViewById(R.id.btnclean);
            btnread = (Button) findViewById(R.id.btnread);
    btnsa ve.setOnClickListener(this);
            btnclean.setOnClickListener(this);
            btnread.setOnClickListener(this);
        }
    @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btnclean:
                    editdetail.setText("");
                    editname.setText("");
                    break;
                case R.id.btnsa ve:
                    String filename = editname.getText().toString();
                    String filedetail = editdetail.getText().toString();
                    SDFileHelper sdHelper = new SDFileHelper(mContext);
                    try
                    {
                        sdHelper.sa vaFileToSD(filename, filedetail);
                        Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();
                    }
                    catch(Exception e){
                        e.printStackTrace();
                        Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();
                    }
                    break;
                case R.id.btnread:
                    String detail = "";
                    SDFileHelper sdHelper2 = new SDFileHelper(mContext);
                    try
                    {
                        String filename2 = editname.getText().toString();
                        detail = sdHelper2.readFromSD(filename2);
                    }
                    catch(IOException e){e.printStackTrace();}
                    Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }

    最后别忘记在AndroidManifest.xml写上读写SD卡的权限哦!

    
    
    
    

    5.关于原生模拟器SD卡的问题

    如果是在真机上调试,这种情况一般都没什么大问题;但一旦换到原生虚拟机,麻烦往往就多了。前面用到的Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)在这类环境里,可能会一直返回false,意思很直接:系统判断SD卡并不存在。这恰恰是最核心的问题。好在新版本的SDK已经考虑到了这一点,通常在创建A VD时,会一并分配一块SD卡存储区域。

    对于旧版本的sdk或者其他原因可能需要手动关联下sd卡,设置如下:
    ①找到创建好的a vd的镜像的路径:
    点击打开a vd界面,点击detail,查看a vd镜像的目录下

    ②来到a vd镜像所在的路径下,复制sdcard.img的路径:
    比如我的:-sdcard C:UsersAdministrator.androida vdJay4.2.a vdsdcard.img

    ③接着点击 来到以下界面:

    最后apply以下,然后Run就可以了!

    6.读取raw和assets文件夹下的文件

    相信大家对两个文件夹并不陌生,如果我们不想自己的文件被编译成二进制文件的话, 我们可以把文件放到这两个目录下,而两者的区别如下:

    • res/raw:文件会被映射到R.ja va文件中,访问的时候直接通过资源ID即可访问,而且 他不能有目录结构,就是不能再创建文件夹
    • assets:不会映射到R.ja va文件中,通过AssetManager来访问,能有目录结构,即, 可以自行创建文件夹

    读取文件资源:

    res/raw:

    InputStream is =getResources().openRawResource(R.raw.filename);  

    assets:

    AssetManager am =  getAssets();  
    InputStream is = am.open("filename");

    代码下载:

    • FileDemo.zip:下载 FileDemo.zip
    • FileDemo2.zip:下载 FileDemo2.zip

    本节小结:

    好的,关于Android的数据存储与访问的第一节——文件读写就到这里,如果在学习本文中 遇到什么问题,或者觉得有些纰漏的地方,欢迎提出,万分感激,谢谢~

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    系统应用 数据存储
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。