文件类型

  1. 应用文件
  2. 用户文件
  3. 系统文件开发者无法修改

具体能力:

① 支持对应用文件进行查看、创建、读写、删除、移动、复制、获取属性等访问操作。

② 支持应用文件上传到网络服务器和网络服务器下载网络资源文件到本地应用文件目录。

③ 支持获取当前应用的存储空间大小、指定文件系统的剩余空间大小和指定文件系统的总空间大小。

④ 支持应用分享文件给其它应用和使用其它应用分享的文件。

⑤ 支持应用接入数据备份恢复,在接入后,应用可通过修改配置文件定制备份恢复框架的行为,包括是否允许备份恢复、备份哪些数据。

⑥ 支持跨设备的文件访问和拷贝能力。

能力特点:

① 沙箱隔离:SandBox,访问和管理应用文件,对于每个应用,系统会在内部存储空间映射出一个专属的“应用沙箱目录”,它是“应用文件目录”与一部分系统文件(应用运行必需的少量系统文件)所在的目录组成的集合。有以下优点:  

  ● 隔离性:应用沙箱提供了一个完全隔离的环境,使用户可以安全地访问应用文件;

  ● 安全性:应用沙箱限制了应用可见的数据的最小范围,保护了应用文件的安全。

(沙箱:鸿蒙允许你访问的 )   看到的目录结构是虚拟的,是鸿蒙想让你看到的,如支付宝里:/1.jpg      把支付宝里的给删了,不会影响微信的文件 微信:/pic/1.jpg ;

后续见的应用路径都是虚拟的

② 应用分享:应用之间可以通过分享URI(Uniform Resource Identifier)或文件描述符FD(File Descriptor)的方式,进行文件共享。有以下优点:    ● 便携性:应用之间文件分享,省去了用户在多个应用间切换的麻烦,简化操作步骤,提高效率;     ● 高效性:应用间的文件分享能够更快地完成文件的传输,减少了因多次跳转和等待而浪费的时间;     ● 数据一致性:应用间的文件分享能够确保数据的完整性和一致性,避免数据在传输过程中出现损坏或丢失的情况;     ● 安全性:应用间的文件分享可以确保文件的安全性,避免文件被非法获取或篡改。同时,通过文件授权访问的方式,可以进一步增强文件的安全性。

应用沙箱

每个应用都有自己的沙箱,彼此不可见!

应用文件

(1)写出应用文件:

Text('向日志文件中写出内容 --- 应用中的普通文件')
        .fontSize(30)
      Button('写出日志')
        .onClick(() => {
          let ctx = getContext();
          let dir = ctx.filesDir
          console.log('应用的普通文件保存目录:' + ctx.filesDir)

          let fileName = dir + '/my01.log' //完整沙箱路径名 /data/storage/el2/base/haps/entry/files/my01.log
          //   1、打开文件,读写模式为: 创建 + 只写
          let f = fileIo.openSync(fileName, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY)
          //   2、写出内容
          let len = fileIo.writeSync(f.fd, 'My Log 01: '+Date.now())
          console.log( '---------写出长度:' + len)
          //   3、关闭文件
          fileIo.closeSync(f)
        })

(2)读取应用文件:

Button('2、读取日志')
        .onClick(async () => {
          let path = getContext().filesDir + '/my01.log' // 完整路径
        //   1、打开文件
          let  f = await fileIo.open(path, fileIo.OpenMode.READ_ONLY)

        //   2、读取文件
          let buf = new ArrayBuffer(1024) // buf对象不能直接输出,必须截取其中有意义的数据
          let len = await fileIo.read(f.fd,buf)
          console.log('读取文件成功,实际读取长度:' + len)
          let data = buffer.from(buf,0,len) // 转换为字符串, 注意:实际读取长度 , 不是buffer的长度, 而是实际读取的长度, 否则会出现乱码
          console.log('读取内容:' +data )

        //   3、关闭文件
          await fileIo.closeSync(f)

        })

(3)拷贝文件

Button('4、拷贝文件')
        .onClick(()=>{

          /*
          CREATE 没有就创建,有的话就从0开始
          * Trang:阶段,保留之前的内容,在结尾追加
          * Append: 追加,保留之前的内容,在结尾追加
          * Truncate: 截断,保留之前的内容,在结尾追加
           */

          let dir = getContext().filesDir
          let srcPath = dir + '/my01.log'; // 要读取的文件
          let destPath = dir + '/my02.log'; // 要写出的目标文件-------如果存在需要先删除

          //   1、打开文件(2个文件)
          let f1  = fileIo.openSync(srcPath, fileIo.OpenMode.READ_ONLY )  //打开原始路径
          let f2 = fileIo.openSync(destPath,fileIo.OpenMode.WRITE_ONLY | fileIo.OpenMode.CREATE)

          //   2、拷贝文件(两个)
          let buf = new ArrayBuffer(40)
          let len = 0;
          while ((len = fileIo.readSync(f1.fd, buf, {length: len}) ) > 0){
            console.log('读取长度:' + len)
            fileIo.writeSync(f2.fd, buf, {length:len})
          }


          //   3、关闭文件
          fileIo.closeSync(f1)
          fileIo.closeSync(f2)

        })

选择用户文件((ohos.file.picker))

简要:

  • PhotoViewPicker:适用于图片或视频类型文件的选择与保存(该接口在后续版本不再演进)。请使用PhotoAccessHelper的PhotoViewPicker来选择图片文件。请使用安全控件保存媒体库资源

  • DocumentViewPicker:适用于文件类型文件的选择与保存。DocumentViewPicker对接的选择资源来自于FilePicker, 负责文件类型的资源管理,文件类型不区分后缀,比如浏览器下载的图片、文档等,都属于文件类型。

  • AudioViewPicker:适用于音频类型文件的选择与保存。AudioViewPicker目前对接的选择资源来自于FilePicker。

(1)PhotoViewPicker:适用于图片或视频类型文件的选择与保存——图库中的资源;

选择图片,并显示出来

import { photoAccessHelper } from '@kit.MediaLibraryKit'

@Entry
@Component
struct Index {
  @State imgSrc: string = ''  // 图片地址

  build() {
    Column() {
      Text('用户文件拾取器')
        .fontSize(30)
      Button('拾取一个用户的图片文件(授权应用访问该文件)')
        .onClick(async () => {
          // let pvp = new picker.photoviewpiker  // 已废弃
          let pvp = new photoAccessHelper.PhotoViewPicker
          let result = await pvp.select({
            maxSelectNumber: 1, // 最大选择数量
            MIMEType:photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE, // 选择文件类型,过滤可选择的文件类型
          }) // 返回所选文件的 URI。
          console.log('返回值:'+JSON.stringify(result))
          console.log('第一张图片的地址:'+JSON.stringify(result.photoUris[0]))
          this.imgSrc = result.photoUris[0]
       })

      Image(this.imgSrc)
        .width('50%')
    }
    .height('100%')
    .width('100%')
  }
}

上传图片给服务器:

 1、拉起一个图片拾取器,让用户选中一张图片
 
//    1、拉起一个图片拾取器,让用户选中一张图片
          let pvp = new photoAccessHelper.PhotoViewPicker
          let result = await pvp.select({
            maxSelectNumber:1, // 最大选择数量
            MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE, // 选择文件类型,过滤可选择的文件类型
          })
          let path = result.photoUris[0]  // 图片地址
2、读取图片内容,放到一个内存缓冲区
 
//   2、读取图片内容,放到一个内存缓冲区
          let f = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY)
          let stat = fileIo.statSync(f.fd)  // 获取文件大小
          // console.log('文件 ' + path + ' 大小:' + stat.size + '字节')
          let buf = new ArrayBuffer(stat.size) // 创建一个缓冲区,缓冲区大小必须大于等于文件大小
          fileIo.readSync(f.fd, buf)   // 一次性读取文件的全部内容
          fileIo.closeSync(f)

3、把缓冲区的数据打包为HTTP请求消息,提交给远程服务器,可以接收文件上传数据的接口

网络请求权限

axios第三方库安装,axios请求:

安装成功:

申请获取令牌,Token。

测试登入接口:

https://www.codeboy.com/chinamobileapi/user/login/email

账户、密码

发送请求

//   3、把缓冲区的数据打包为HTTP请求消息,提交给远程服务器,可以接收文件上传数据的接口
          let url = 'https://www.codeboy.com/chinamobileapi/user/update/avatar'
          let data =
            new FormData() // 表单数据,用于提交给服务器,可以接收文件上传数据的接口,表单数据格式:multipart/form-data,文件上传格式:application/octet-stream
          data.append('avatar', buf) // 在表单对象中追加一个上传的文件

          let res: AxiosResponse = await axios.post(url, data, {
            headers: {
              'Content-Type': 'multipart/form-data',
              'token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEsInBob25lIjoiMTM1MDEyMzQ1NjciLCJlbWFpbCI6InlhQHRlZHUuY24iLCJjcmVhdGVkIjoxNzQxNzQyMDc2MDYwLCJleHBpcmVzIjoxNzQxODI4NDc2MDYwLCJpYXQiOjE3NDE3NDIwNzZ9.caTBhzj58zLTqcrO3nQMblj73jKxzsOeW2fQ1NZljm4\n'
            }
          })

          console.log('---头像文件上传请求获得的消息:', JSON.stringify(res.data))

完整代码:

Button('拾取一个用户的视频文件(授权应用访问该文件),上传用户头像给服务器')
        .onClick(async () => {
          //    1、拉起一个图片拾取器,让用户选中一张图片
          let pvp = new photoAccessHelper.PhotoViewPicker
          let result = await pvp.select({
            maxSelectNumber: 1, // 最大选择数量
            MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE, // 选择文件类型,过滤可选择的文件类型
          })
          let path = result.photoUris[0] // 图片地址

          //   2、读取图片内容,放到一个内存缓冲区
          let f = fileIo.openSync(path, fileIo.OpenMode.READ_ONLY)
          let stat = fileIo.statSync(f.fd) // 获取文件大小
          // console.log('文件 ' + path + ' 大小:' + stat.size + '字节')
          let buf = new ArrayBuffer(stat.size) // 创建一个缓冲区,缓冲区大小必须大于等于文件大小
          fileIo.readSync(f.fd, buf) // 一次性读取文件的全部内容
          fileIo.closeSync(f)

          //   3、把缓冲区的数据打包为HTTP请求消息,提交给远程服务器,可以接收文件上传数据的接口
          let url = 'https://www.codeboy.com/chinamobileapi/user/update/avatar'
          let data =
            new FormData() // 表单数据,用于提交给服务器,可以接收文件上传数据的接口,表单数据格式:multipart/form-data,文件上传格式:application/octet-stream
          data.append('avatar', buf) // 在表单对象中追加一个上传的文件

          let res: AxiosResponse = await axios.post(url, data, {
            headers: {
              'Content-Type': 'multipart/form-data',
              'token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEsInBob25lIjoiMTM1MDEyMzQ1NjciLCJlbWFpbCI6InlhQHRlZHUuY24iLCJjcmVhdGVkIjoxNzQxNzQyMDc2MDYwLCJleHBpcmVzIjoxNzQxODI4NDc2MDYwLCJpYXQiOjE3NDE3NDIwNzZ9.caTBhzj58zLTqcrO3nQMblj73jKxzsOeW2fQ1NZljm4\n'
            }
          })

          console.log('---头像文件上传请求获得的消息:', JSON.stringify(res.data))
        })

下载图片

(2)DocumentViewPicker:适用于文件类型文件的选择与保存——如浏览器下载的文档等;

(3)AudioViewPicker:适用于音频类型文件的选择与保存。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐