文章目录

  • 一、文件存储类型
    • (一)内部存储
      • 1、内部文件概念
      • 2、文件读写方法
      • 3、缓存文件目录
    • (二)外部存储
      • 1、外部文件概念
      • 2、编程对SD卡数据读写
  • 二、案例演示 - 文件操作
    • (一)运行结果
    • (二)涉及知识点
    • (三)实现步骤
      • 1、创建安卓应用【FileOperation】
      • 2、将背景图片拷贝到drawable目录
      • 3、主布局资源文件activity_main.xml
      • 4、字符串资源文件strings.xml
      • 5、在raw目录里创建文件 - test.txt
      • 6、在assets目录里创建文件 - test.txt
      • 7、主界面类 - MainActivity
        • (1)编写代码读取raw目录里的文件
        • (2)编写代码读取assets目录里的文件
        • (3)编写代码写入应用files目录里的文件
        • (4)编写代码读取应用files目录里的文件
        • (5)编写代码写入SDCard的文件
        • (6)编写代码读取SDCard上的文件
      • 8、查看主界面源代码
  • 三、如何将电脑文件添加到外置存储卡
  • 四、课后作业
    • 任务:编写一个简易电子书程序。

上一讲,我们学习了如何利用共享参数读写一些简单的配置信息,以键值对的方式来存储信息,但是如果处理一般的文本文件、音视频文件或图像文件,那么就必须利用文件流来进行处理。

一、文件存储类型

(一)内部存储

1、内部文件概念

安卓系统允许程序创建自身访问的私有文件,并且把文件保存在设备的内部存储器中的/data/data/<package name>/files目录下。比如我们查看安卓应用(com.google.android.youtube)下的files目录:

2、文件读写方法

  • 针对私有文件(应用files目录里的文件),通过openFileInput()方法获得文件输入流(FileInputStream ),利用它可以读取文件内容;通过openFileOutput()方法获得文件输出流(FileOutputStream),利用它可以把数据写入文件。
  • 安卓应用里raw目录和assets目录存放的文件可以读取,但是要注意不能写入。
  • 对于raw目录的文件:InputStream in = getResources().openRawResource(文件资源标识);
  • 对于assets目录的文件:InputStream in = getResources().getAssets.open(文件名字符串);

3、缓存文件目录

  • 安卓系统还提供了一个保存文件的缓存目录:/data/data/<package name>/cache

(二)外部存储

1、外部文件概念

外部存储主要指的是将数据文件存储到设备的SD卡上。SD卡(Secure Digital Memory Card)是一种数码设备上通常使用的记忆卡,其容量比设备内置闪存要大很多。

2、编程对SD卡数据读写

(1)授权访问外置存储卡(SDCard)

  • 在项目清单文件里AndroidManifest.xml中加入访问SDCard的权限
 <!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 从SDCard读取数据权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

(2)判断手机环境是否可以使用外置存储卡

  • 在进行读写之前,应该先判断该手机环境是否具备 SD 卡,Environment类用于得到手机环境,其getExternalStorageState( )方法用于获取手机外部存储设备(SD卡)的状态,如果为false,表示没有SD卡使用环境。其使用方法如下所示:Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); 判断手机是否存在SD卡,并是可读写的。

(3)文件读写操作

  • 利用文件输入流(FileInputStream)与文件输出流(FileOutputStream)对外置存储卡上的文件进行读写操作。

二、案例演示 - 文件操作

(一)运行结果

(二)涉及知识点

  1. 线性布局(LinearLayout)
  2. 按钮(Button)
  3. 字节输入流(InputStream)
  4. 文件输入流(FileInputStream)
  5. 文件输出流(FileOutputStream)

(三)实现步骤

1、创建安卓应用【FileOperation】


2、将背景图片拷贝到drawable目录

3、主布局资源文件activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/background"android:orientation="vertical"android:padding="10dp" ><Buttonandroid:id="@+id/btnReadRawFile"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doReadRawFile"android:text="@string/read_raw_file" /><Buttonandroid:id="@+id/btnReadAssetsFile"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doReadAssetsFile"android:text="@string/read_assets_file" /><Buttonandroid:id="@+id/btnWriteAppFile"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doWriteAppFile"android:text="@string/write_app_file" /><Buttonandroid:id="@+id/btnReadAppFile"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doReadAppFile"android:text="@string/read_app_file" /><Buttonandroid:id="@+id/btnWriteSDCardFile"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doWriteSDCardFile"android:text="@string/write_sdcard_file" /><Buttonandroid:id="@+id/btnReadSDCardFile"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doReadSDCardFile"android:text="@string/read_sdcard_file" /><ScrollViewandroid:id="@+id/scrollview"android:layout_width="match_parent"android:layout_height="wrap_content"android:scrollbars="vertical" ><TextViewandroid:id="@+id/tvFileContent"android:layout_width="match_parent"android:layout_height="match_parent" /></ScrollView>
</LinearLayout>

4、字符串资源文件strings.xml

<resources><string name="app_name">文件操作</string><string name="read_raw_file">读取raw目录里的文件</string><string name="read_assets_file">读取assets目录里的文件</string><string name="write_app_file">写入应用files目录里的文件</string><string name="read_app_file">读取应用files目录里的文件</string><string name="write_sdcard_file">写入sdcard上的文件</string><string name="read_sdcard_file">读取sdcard上的文件</string>
</resources>

5、在raw目录里创建文件 - test.txt

  • 在res目录里创建raw目录,然后在raw目录里创建test.txt

超越免费

今天是我们第二季专栏的第四周,在前几周里,我会把这一季四种主题的内容分别刊登一两周,这样你会对全年的内容有真实的感受。

这一周我们会围绕工作方法和商业本质展开。

免费这件事情在个人电脑出现之后,其实就很难避免了,因为只要有了可以迅速大量“写”信息的设备,比如早期的磁盘机,后来的激光盘读写机,以及再后来的互联网,大众可以不借助第三方盗版厂家,自行获得免费信息、软件、和音视频内容。

一开始的时候,微软等公司还在中国打击盗版,那时,微软的 CEO 鲍尔默每年要到中国一两次,解决这个问题。

但是到后来他干脆带有戏谑和苦涩的口吻说,如果你们要盗版,能否盗正版。言外之意,不如问我要正版软件,不要再去市场上找那些感染了病毒的各种盗版了。

这时,很多 IT 产品和文化创意产品就不可避免地开始免费了。

到了互联网时代,雅虎的杨致远和费罗首创了免费的互联网服务,并且找到了广告这种商业模式,这才让互联网成为一个开放、免费的工具。

因此,我在《浪潮之巅》一书中讲,再过几十年大家回顾互联网发展史的时候会发现,杨致远和费罗英明不朽,因为他们确定了互联网的格局。

6、在assets目录里创建文件 - test.txt

  • 切换到Project视图,在main目录里创建assets目录,然后在assets目录里创建test.txt

初学者之心

我们精英日课学习了斯坦尼斯拉斯·迪昂的《我们如何学习》,对大脑的“可塑性”非常关心。脑神经科学意义上的可塑性是一个底层的限制,这一讲咱们说说心理学意义上的大脑可塑性,可能会对你更有用。这个可塑性,一般的说法叫“开放的头脑”,高级的说法叫“智识的谦逊(intellectual humility )”。

智识谦逊是一个思想状态,是一个境界。智识谦逊的人愿意接触新东西、愿意学习新知识 —— 你的大脑在心理学上是可塑的,所以你才能学到新知识。反过来说,如果一个人故步自封、充满成见,根本就不愿意再去接触新东西,那他的前额叶皮质到底有多可塑其实意义不大。

保持智识谦逊对你的大脑可能有直接的好处。很多老年人抱怨自己的认知能力,说是上了年纪之后做事丢三落四,读书记不住,一思考复杂问题就累了,但是我最近看到一个研究说,那些有开放头脑的老年人就不抱怨这些。他们乐于探索新鲜的智力活动,愿意思考,敢于挑战难题。他们的大脑得到了更多锻炼,对自己的认知能更自信。

当然也许有的人只是被生活所迫压力太大而根本没机会去搞什么智力活动,开放心态首先是一个幸运的状态。但是我相信,任何人都可以追求这个状态。开放心态和智识谦逊是现在很热门的研究课题,我们专栏就讲过好几次。最近心理学科学作家克里斯蒂安·贾瑞特(Christian Jarrett)写了一篇综述性的文章,对相关的研究做了比较系统的介绍,我们可以从中总结几个有用的知识。

  • 切换到Android视图,查看assets目录里的test.txt

7、主界面类 - MainActivity

  • 声明变量
  • 通过资源标识符获取控件实例

(1)编写代码读取raw目录里的文件

  • 启动应用,查看效果

(2)编写代码读取assets目录里的文件

  • 启动应用,查看效果

(3)编写代码写入应用files目录里的文件

  • 启动应用,查看效果
  • 在DDMS的File Explorer里查看生成的文件

  • 利用adb shell来授权
adb root
adb shell
chmod 777 /data
chmod 777 /data/data
chmod 777 /data/data/net.hw.file_operation
chmod 777 /data/data/net.hw.file_operation/files
chmod 777 /data/data/net.hw.file_operation/files/test.txt

  • 在File Explorer里访问test.txt文件

(4)编写代码读取应用files目录里的文件

  • 启动应用,查看效果

(5)编写代码写入SDCard的文件

  • 启动应用,查看效果
  • 打开项目清单文件,授权读写外置存储卡
    - 启动应用,查看效果

  • 可以看到,storage、storage\emulated、storage\emulated\0的访问权限不够
  • 利用adb shell给这些目录授权

  • 可以看到,只有/storage访问权限被改了,但是/storage/emulated和/storage/emulated/0两个目录的访问权限依然如故,不知道是什么原因导致无法修改。
  • 经过网上搜索,得知安卓7.0读写存储卡,不仅需要在项目清单文件里授权,还需要在Java代码里请求授权。
  • 启动应用,查看效果
  • 在File Explorer里查看刚才创建的文件

(6)编写代码读取SDCard上的文件

  • 先删除文件
  • 启动应用,查看效果

8、查看主界面源代码

package net.hw.file_operation;import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;public class MainActivity extends AppCompatActivity {private TextView tvFileContent; // 显示文件内容的标签@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 利用布局资源文件设置用户界面setContentView(R.layout.activity_main);// 通过资源标识符获取控件实例tvFileContent = findViewById(R.id.tvFileContent);}/*** 读取raw目录里的文件** @param view*/public void doReadRawFile(View view) {// 打开raw目录里的文件,获取字节输入流InputStream in = getResources().openRawResource(R.raw.test);try {// 获取字节输入流长度int length = in.available();// 定义字节缓冲区byte[] buffer = new byte[length];// 读取字节输入流数据,存放到字节缓冲区in.read(buffer);// 关闭字节输入流in.close();// 将字节缓冲区内容转换成字符串String content = new String(buffer, "UTF8");// 设置标签文本颜色tvFileContent.setTextColor(Color.RED);// 设置标签文本tvFileContent.setText(content);} catch (IOException e) {e.printStackTrace();}}/*** 读取assets目录里的文件** @param view*/public void doReadAssetsFile(View view) {// 定义文件名String filename = "test.txt";try {// 打开assets目录里的文件,获取字节输入流InputStream in = getResources().getAssets().open(filename);// 定义字符串构建器StringBuilder builder = new StringBuilder();// 定义字节缓冲区byte[] buffer = new byte[512];// 通过遍历读玩字节输入流int len = 0;while ((len = in.read(buffer)) != -1) {builder.append(new String(Arrays.copyOf(buffer, len), "UTF8"));}// 关闭字节输入流in.close();// 获取字符串构建器的字符串String content = builder.toString();// 设置标签文本颜色tvFileContent.setTextColor(Color.BLUE);// 设置标签文本tvFileContent.setText(content);} catch (IOException e) {e.printStackTrace();}}/*** 写入应用files目录里的文件** @param view*/public void doWriteAppFile(View view) {// 定义文件名String filename = "test.txt";// 定义文件访问模式int mode = Context.MODE_PRIVATE;try {// 获取文件字节输出流FileOutputStream fos = openFileOutput(filename, mode);// 创建文件内容字符串String content = "登鹳雀楼\n\n白日依山尽,\n黄河入海流。\n欲穷千里目,\n更上一层楼。";// 将字符串转成字节数组byte[] buffer = content.getBytes("UTF8");// 将字节数组写入指定文件fos.write(buffer);// 关闭文件字节输出流fos.close();// 提示用户文件写入成功!Toast.makeText(this, "恭喜,写入文件成功!", Toast.LENGTH_SHORT).show();} catch (IOException e) {// 提示用户文件写入失败!Toast.makeText(this, "遗憾,写入文件失败!", Toast.LENGTH_SHORT).show();}}/*** 读取应用files目录里的文件** @param view*/public void doReadAppFile(View view) {// 定义文件名String filename = "test.txt";try {// 获取文件字节输入流FileInputStream fis = openFileInput(filename);// 获取文件字节输入流长度int length = fis.available();// 定义字节数组,存放字节输入流全部内容byte[] buffer = new byte[length];// 读取文件字节输入流,内容保存到字节数组里fis.read(buffer);// 关闭文件字节输入流fis.close();// 将字节数组转换成字符串String content = new String(buffer, "UTF8");// 设置标签文本颜色tvFileContent.setTextColor(Color.GREEN);// 设置标签文本字号tvFileContent.setTextSize(20);// 设置标签文本tvFileContent.setText(content);} catch (IOException e) {e.printStackTrace();}}/*** 写入SDCard上的文件(需要授权)** @param view*/public void doWriteSDCardFile(View view) {// 定义存储读写权限数组String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};// 检查是否有写权限int permission = ActivityCompat.checkSelfPermission(this, PERMISSIONS_STORAGE[1]);// 如果没有授权,那么就请求写权限if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 1);}// 获取SDCard根目录String path = Environment.getExternalStorageDirectory().getPath();// 定义文件名String filename = "test.txt";// 创建文件对象File file = new File(path, filename);try {// 创建文件字节输出流FileOutputStream fos = new FileOutputStream(file);// 创建文件内容字符串String content = "静夜思\n\n床前明月光,\n疑是地上霜。\n举头望明月,\n低头思故乡。";// 将字符串转换成字节数组byte[] buffer = content.getBytes("UTF8");// 将字节数组写入指定文件fos.write(buffer);// 关闭字节输出流fos.close();// 弹出吐司告诉用户写入成功Toast.makeText(this, "恭喜,写入文件成功!", Toast.LENGTH_SHORT).show();} catch (IOException e) {e.printStackTrace();// 弹出吐司告诉用户写入失败Toast.makeText(this, "遗憾,写入文件失败!", Toast.LENGTH_SHORT).show();}}/*** 读取SDCard上的文件(需要授权)** @param view*/public void doReadSDCardFile(View view) {// 定义存储读写权限数组String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};// 检查是否有读权限int permission = ActivityCompat.checkSelfPermission(this, PERMISSIONS_STORAGE[0]);// 如果没有授权,那么就请求读权限if (permission != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 0);}// 获取SDCard根目录String path = Environment.getExternalStorageDirectory().getPath();// 定义文件名String filename = "test.txt";// 创建文件对象File file = new File(path, filename);try {// 创建文件字节输入流FileInputStream fis = new FileInputStream(file);// 获取文件字节输入流长度int length = fis.available();// 定义字节数组byte[] buffer = new byte[length];// 读取文件字节输入流,保存到字节数组fis.read(buffer);// 关闭文件字节输入流fis.close();// 将字节数组转换成字符串String content = new String(buffer, "UTF8");// 设置标签文本颜色tvFileContent.setTextColor(Color.rgb(255, 0, 255));// 设置标签文本字号tvFileContent.setTextSize(20);// 设置标签文本tvFileContent.setText(content);} catch (IOException e) {// 弹出吐司提示用户读取失败Toast.makeText(this, "遗憾,读取文件失败!", Toast.LENGTH_SHORT).show();}}
}

三、如何将电脑文件添加到外置存储卡

  • 将电脑文件添加到外置存储卡根目录 - /storage/emulated/0
  • 将mp3音乐文件添加到公共目录 - /storage/emulated/0/Music
  • Java代码里访问音乐公共目录:Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
  • 查看从电脑上添加到存储卡上的文件

四、课后作业

任务:编写一个简易电子书程序。

  1. 主窗口列表显示全部文章名
  2. 每篇文章都保存在存储卡文件里
  3. 单击文章名,在新窗口显示文章内容
  4. 新窗口包含返回目录按钮
  5. 单击返回目录按钮,返回主窗口

安卓学习笔记28:文件流操作相关推荐

  1. 安卓学习 Day23:文件流操作

    文件流操作 一.案例演示--文件操作 1.创建安卓应用 2.添加背景图片 3.字符串资源文件 4.主布局资源文件 5.在raw目录里创建文件 - test.txt 6.在assets目录里创建文件 - ...

  2. Android学习笔记---13_文件的操作模式.各个应用之间的文件权限

    2013-03-05 13_文件的操作模式 --------------------------------------- 1.注意在应用相同的情况下,不同的项目一定不要用相同的包名这样的话,会被视为 ...

  3. 2020年安卓学习笔记目录

    文章目录 一.讲课笔记 二.安卓案例 三.安卓实训项目 四.学生安卓学习博客 五.安卓课后作业 (一)界面设计练习 1.制作登录界面 2.制作部队管理界面 3.制作灭火救援界面 4.制作交付界面 5. ...

  4. 安卓学习笔记27:共享参数

    文章目录 零.学习目标 一.数据存储 二.共享参数 (一)共享参数概述 (二)利用共享参数读写文件步骤 三.案例演示--读写数据 (一)运行效果 (二)实现步骤 1.创建安卓应用[ReadWriteD ...

  5. 很low的安卓学习笔记(一、实用技巧)

    很low的安卓学习笔记(一.实用技巧) 一.学习了几天的实用技巧小总结: 1.规范的定义内容的格式: 2.一些快捷键 3.将xxx.xml布局改为Activity中可以调用的View视图 4.当左下角 ...

  6. 安卓学习笔记3——登录界面UI

    安卓学习笔记3--登录界面UI 一.登录界面UI 1.根据需求写UI 2.主活动 3.主活动调用的读写文件的工具类 4.效果展示 二.总结与改进 不足: 1.密码分割采用字符串:当密码和用户名包含该字 ...

  7. Python学习笔记28:从协议到抽象基类

    Python学习笔记28:从协议到抽象基类 今后本系列笔记的示例代码都将存放在Github项目:https://github.com/icexmoon/python-learning-notes 在P ...

  8. C# 学习笔记(17)操作SQL Server 上

    C# 学习笔记(17)操作SQL Server上 安装SQL Server 微软官网 https://www.microsoft.com/zh-cn/sql-server/sql-server-dow ...

  9. android中资源文件的两种访问方式,Android_Android学习笔记-保存文件(Saving Files),Android设备有两种文件存储区域 - phpStudy...

    Android学习笔记-保存文件(Saving Files) Android设备有两种文件存储区域: 内部存储和外部存储 ("internal" and "externa ...

最新文章

  1. QT中使用rubberband橡皮筋等方法进行选中多个物体
  2. iOS_“图片浏览选择”功能的编写思路
  3. c odac 连接 oracle,使用ODAC112040Xcopy_64bit 将sql server连接到oracle
  4. Docker(三):Dockerfile 命令详解
  5. 计算机操作简介,什么是计算机操作的快捷键?计算机操作快捷方式简介
  6. android 调用java接口_android调用java的web service接口
  7. 程序员每天少吃===活120岁
  8. springBoot shiro
  9. torchtext建立词表build_vocab()时使用自己的word2vec模型
  10. 他35k月薪,如何扛住redis面试!
  11. Centos 启动过程详解
  12. response.sendRedirect(url)与request.getRequestDispatcher(url).forward(request,response)的区别
  13. 小甲鱼 C语言 19课 字符串的处理函数
  14. ORACLE RAC 11.2.0.4 一节点出现Suspending MMON slave action kewrmrfsa_ for 82800 seconds
  15. Animation之闪烁的星星
  16. [loj6388] 「THUPC2018」赛艇 / Citing
  17. coap php 发送,CoAP 客户端
  18. Live Home 3D for Mac汉化破解版永久激活方法
  19. 微信浏览器调用手机摄像头录像
  20. pymol配体平移与旋转

热门文章

  1. 掌握JS压缩图片,这一篇就够了
  2. Flask自定义时间过滤器
  3. php的floorval函数,php 取整函数(floor,ceil,round,intval)_PHP教程
  4. python磁盘io_Python多线程同步、互斥锁、死锁
  5. Java TCP/UDP编程
  6. 优达学城深度学习之五——卷积神经网络
  7. android 多平台发布,内容多平台发布
  8. python大鱼吃小鱼程序代码_最近跟导师学Python,熬夜弄了两个晚上写出来个大鱼吃小鱼游戏!...
  9. Java实现二维码生成
  10. 大佬应该都懂的python语法,看看哪些是你不知道的?