HarmonyOS鸿蒙Next中封装文件上传

HarmonyOS鸿蒙Next中封装文件上传 应用文件上传下载:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/app-file-upload-download

使用Picker选择媒体库资源:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/photoaccesshelper-photoviewpicker

1、上传应用文件

说明

当前上传应用文件功能。request.uploadFile方式仅支持上传应用缓存文件路径(cacheDir)下的文件,request.agent方式支持上传用户公共文件和应用缓存文件路径下的文件。

使用上传下载模块,需声明权限:
ohos.permission.INTERNET。

// 1、获取文件上下文
let context=getContext(this) as common.UIAbilityContext
// 获取到缓存的文件路径
let cacheDir=context.cacheDir

/**
 * 封装文件上传函数
 */
export function FileUpload(){
  // 2、准备上传需要的数据结构
  // 新建一个本地应用文件,赋予读写和创建的权限
  let file =fs.openSync(cacheDir+'/test.txt',fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE)
  // 在文件中写入数据
  fs.writeSync(file.fd,'upload file test')
  // 关闭写入
  fs.closeSync(file)

  // 上传任务配置项
  let header=new Map<Object,string>()
  // multipart/form-data代表可以上传多个文件
  header.set('Content-type','multipart/form-data')

  // 准备上传的文件对象
  let files:Array<request.File>=[
    {filename:'test',name:'file',uri:'internal://cache/test.txt',type:'txt'}
  ]
  // 文件上传的时候,给服务传递参数
  let data:Array<request.RequestData>=[{name:'name',value:'value'}]
  // 文件上传的参数对象
  let uploadConfig:request.UploadConfig={
    url:'http://nocat.life:3012/images/upload',
    header:header,
    method:'POST',
    files:files,
    data:data
  }
  // 3、 将本地应用文件上传至网络服务器
  try {
    request.uploadFile(context,uploadConfig)
      .then((uploadTask:request.UploadTask)=>{
        // 监听上传状态
        uploadTask.on('complete',(taskStates:Array<request.TaskState>)=>{
          // 上传的时候可能上传多个文件,每个文件结果循环打印出来
          for (let index = 0; index < taskStates.length; index++) {
            console.info(`upload complete taskState:${JSON.stringify(taskStates[index])}`)
          }
        })
      })
      .catch((err:BusinessError)=>{
        console.error(`Invoke uploadFile failed,code is ${err.code},message is ${err.message}`)
      })
  } catch (error) {
    let err:BusinessError=error as BusinessError
    console.error(`Invoke uploadFile failed,code is ${err.code},message is ${err.message}`)
  }
}

页面代码:

import { FileUpload, PickerPhoto, UpdateFileUpload } from '../utils/FileUpload';

@Entry
@Component
struct DataPage {
  @State imgSrc:string|undefined=''

  build() {
    Column() {
      Button('点击上传')
        .onClick(event=>{
          FileUpload()
        })
    }
    .height('100%')
    .width('100%')
  }
}

2、打开资源库

工具代码:

/**
 * 从本地获取一张图片
 *
 */
export async function PickerPhoto(){
  // 打开系统图库
  const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions()
  // 最多选择一张图片
  photoSelectOptions.maxSelectNumber=1
  // 限制用户只能访问相册资源
  photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE

  // 获取你相册图片地址
  const photoViewPicker = new photoAccessHelper.PhotoViewPicker()
  let urls= await photoViewPicker.select(photoSelectOptions)
  if(urls.photoUris.length<=0){
    return
  }

  let imgUrl=urls.photoUris[0]
  console.log(`选中图片的地址${imgUrl}`)
  return imgUrl
}

页面代码:

import { FileUpload, PickerPhoto, UpdateFileUpload } from '../utils/FileUpload';

@Entry
@Component
struct DataPage {
  @State imgSrc:string|undefined=''

  build() {
    Column() {
      Image(this.imgSrc)
        .width('100%')
        .height(200)
      Button('选择一张图片')
        .onClick(async ()=>{
          const res=await PickerPhoto()
          this.imgSrc=res
        })
    }
    .height('100%')
    .width('100%')
  }
}

3、将本地图库文件拷贝到cache目录

/**
 * 将本地图库文件,拷贝到cache缓存目录
 * [@param](/user/param) photoImgPath
 */
export function copyImgToCache(photoImgPath:string){
  const file=fs.openSync(photoImgPath,fs.OpenMode.READ_ONLY)
  // 文件的唯一标识
  let fileFD=file.fd

  let fileName=Date.now().toString()
  const ext='jpg'
  let fullPath=cacheDir+'/'+fileName+'.'+ext
  fs.copyFileSync(fileFD,fullPath)

  return [`internal://cache/${fileName+'.'+ext}`,fileName+'.'+ext]
}

4、改造FileUpload

工具代码:

/**
 * 改造FileUpload方法
 * [@param](/user/param) imgSrc
 */
export function UpdateFileUpload(imgSrc:string){
  // 2、准备上传需要的数据结构
  // 新建一个本地应用文件,赋予读写和创建的权限
  // let file =fs.openSync(cacheDir+'/test.txt',fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE)
  // // 在文件中写入数据
  // fs.writeSync(file.fd,'upload file test')
  // // 关闭写入
  // fs.closeSync(file)
  const array=copyImgToCache(imgSrc)

  // 上传任务配置项
  let header=new Map<Object,string>()
  // multipart/form-data代表可以上传多个文件
  header.set('Content-type','multipart/form-data')

  // 准备上传的文件对象
  let files:Array<request.File>[

更多关于HarmonyOS鸿蒙Next中封装文件上传的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

在HarmonyOS Next中封装文件上传可使用@ohos.request模块的uploadTask方法。示例代码:

import request from '@ohos.request';

let uploadTask = request.uploadFile({
  url: 'https://example.com/upload',
  files: [
    {
      name: 'file1',
      uri: 'internal://cache/test.jpg'
    }
  ],
  data: [
    {
      name: 'param1',
      value: 'value1'
    }
  ]
});

uploadTask.on('progress', (uploaded, total) => {
  console.log(`进度: ${uploaded}/${total}`);
});

关键点:使用URI定位文件,支持多文件上传和表单数据。上传进度通过事件监听。

更多关于HarmonyOS鸿蒙Next中封装文件上传的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中封装文件上传功能时,需要注意以下几点关键实现:

  1. 文件路径处理:
  • 使用context.cacheDir获取应用缓存目录
  • 注意uploadFile方法仅支持缓存目录文件,而agent方式支持公共文件
  1. 文件操作:
  • 使用fs.openSync创建/打开文件
  • 通过fs.writeSync写入数据
  • 操作完成后调用fs.closeSync
  1. 上传配置:
  • 设置multipart/form-data的Content-Type
  • 构建包含filename、name、uri、type的文件对象数组
  • 可附加额外的表单数据
  1. 媒体文件处理:
  • 使用PhotoViewPicker选择图片
  • 通过copyFileSync将媒体文件复制到缓存目录
  • 注意文件URI格式为internal://cache/文件名
  1. 上传监控:
  • 通过uploadTask.on('complete')监听上传完成事件
  • 正确处理多文件上传的情况

代码中已经展示了完整的实现流程,包括基础文件上传、媒体文件选择和转换上传。关键点在于正确处理文件路径和URI,以及配置正确的上传参数。

对于权限方面,记得在配置文件中声明ohos.permission.INTERNET网络权限。

回到顶部