HarmonyOS鸿蒙Next中使用request.uploadFile上传3MB PPT,上传的文件损坏

HarmonyOS鸿蒙Next中使用request.uploadFile上传3MB PPT,上传的文件损坏 使用request.uploadFile上传PPT文件,KB级的文件不会出现问题,但是MB级别的文件视乎有点问题,我上传3.5MB的文件,有几乎一半的概率会导致上传的文件只剩3.1MB;上传6MB的文件大概率只剩下不到4MB。我这边使用安卓上传这些文件都是没有问题的,鸿蒙这边上传不知道为什么会导致文件损坏,后续我用web打开PPT失败。

8 回复

对比一下官方上传文件的代码,看看有啥地方写错了吗?

async requestUploadFile(fileName: string, callback: (progress: number, isSuccess: boolean) => void,
  context: common.UIAbilityContext) {
  // 获取应用文件路径
  // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
  let url = await urlUtils.getUrl(context);
  let cacheDir = context.cacheDir;
  // 新建一个本地应用文件
  try {
    let file = fs.openSync(cacheDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
    fs.writeSync(file.fd, 'upload file test');
    fs.closeSync(file);
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    logger.error(TAG, `Invoke uploadFile failed, code=${err.code}, message=${err.message}`);
  }
  // 上传任务配置项
  let files: request.File[] = [
  //uri前缀internal://cache 对应cacheDir目录
    {
      filename: fileName,
      name: 'test',
      uri: 'internal://cache/' + fileName,
      type: 'txt'
    }
  ]
  let data: request.RequestData[] = [{ name: 'name', value: 'value' }];
  let uploadConfig: request.UploadConfig = {
    url: url,
    header: {
      'key1': 'value1',
      'key2': 'value2'
    },
    method: 'POST',
    files: files,
    data: data
  }
  // 将本地应用文件上传至网络服务器
  try {
    request.uploadFile(context, uploadConfig)
      .then((uploadTask: request.UploadTask) => {
        uploadTask.on('complete', (taskStates: Array<request.TaskState>) => {
          for (let i = 0; i < taskStates.length; i++) {
            logger.info(TAG, `upload complete taskState: ${JSON.stringify(taskStates[i])}`);
          }
          callback(100, true);
        });
      })
      .catch((err: BusinessError) => {
        logger.error(TAG, `Invoke uploadFile failed, code=${err.code}, message=${err.message}`);
      })
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    logger.error(TAG, `Invoke uploadFile failed, code=${err.code}, message=${err.message}`);
  }
}

更多关于HarmonyOS鸿蒙Next中使用request.uploadFile上传3MB PPT,上传的文件损坏的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我在上传一些小文件都是正常的,几乎不会出现问题。我的代码在运行的时候也没见啥报错提示。还有我用的是request.uploadfile,可能跟你的方法不太一样,我这边对接后端的接口,

改成request.uploadfile了~~,

好的,谢谢你,已经解决了。不小心写了个小错误,

可以给大家看看我上传部分的代码,我本人没发现什么问题

uploadPPTFn(fileUrl: string): void {
  let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  let uploadTask: request.UploadTask;
  let fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
  this.fileName = decodeURI(fileName)
  this.uploadTitle = this.fileName
  let newpath = context.cacheDir + "/"+fileName//+".pptx";
  fs.open(fileUrl,2).then((file: fs.File) => {
    console.info("file fd: " + file.fd);
    fs.copyFile(file.fd, newpath, (err: BusinessError) => {
      if (err) {
        this.uploadStatus = 'fault'
        console.error("copy file failed with error message: " + err.message + ", error code: " + err.code);
        return
      } else {
        console.info("copy file succeed");
      }
      fs.closeSync(file);
    });
  }).catch((err: BusinessError) => {
    this.uploadStatus = 'fault'
    console.error("open file failed with error message: " + err.message + ", error code: " + err.code);
    return
  });
  //获取文件大小
  this.getFileSize(newpath);
  let realuri = "internal://cache/" + newpath.split("cache/")[1]//.split(".pptx")[0]+".pptx";
  console.log('applog:realuri' + realuri);
  //获取了沙箱真实internal格式路径,继续对照准备参数

  let uploadConfig: request.UploadConfig = {
    url: Const.G_AjaxApi_activity + "/api/ai/uploadPPT", // HTTP协议地址
    header: { "Content-Type": "multipart/form-data" },
    method: "POST",
    files: [{
      filename: fileName,
      name: "file",
      uri: realuri,
      type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
    }], // 建议type填写HTTP协议规范的MIME类型
    data: [{ name: "guid", value: this.guid },
      { name: "appID", value: this.appId.toString() },
      { name: "presentations_id", value: this.presentations_id.toString()},
      { name: "provinces", value: this.province },],
  };

  try {
    request.uploadFile(getContext(this), uploadConfig).then((data:request.UploadTask) => {
      uploadTask = data;
      console.log('上传文件成功:');
      uploadTask.on("complete",(data)=>{
        console.log("上传完成:"+JSON.stringify(data))
      })
      uploadTask.on("headerReceive",(data)=>{
        console.log("headerReceive"+JSON.stringify(data))
        let result:uploadResponse = data as uploadResponse
        console.log("***"+result.body)
        let tempUrl = result.body.split('url":"')[1]
        let tempName = tempUrl.split('","name":"')[1]
        let tempOssPath = tempName.split('","ossPath":"')[1]
        let tempPresentations_id = tempOssPath.split('","presentations_id":')[1]

        tempUrl = tempUrl.split('","name":"')[0]
        tempName = tempName.split('","ossPath":"')[0]
        tempOssPath = tempOssPath.split('","presentations_id":')[0]
        tempPresentations_id = tempPresentations_id.split(',')[0]

        this.uploadData.url = tempUrl
        this.uploadData.name = tempName
        this.uploadData.ossPath = tempOssPath
        this.uploadData.presentations_id = Number.parseInt(tempPresentations_id)
        this.uploadStatus = 'complete'
        console.log("PPT上传全过程结束"+JSON.stringify(this.uploadData))
      })
    }).catch((e: BusinessError) => {
      this.uploadStatus = 'fault'
      console.error('Failed to request the upload. Cause: ' + JSON.stringify(e));
    });

  } catch (err) {
    this.uploadStatus = 'fault'
    console.error('applog:' + JSON.stringify(err));
    console.error('err.code : ' + err.code + ', err.message : ' + err.message);
  }
}

在HarmonyOS Next中,使用request.uploadFile上传3MB PPT文件损坏,可能原因包括:

  1. 文件编码或格式处理不当,上传前需确保二进制数据正确。
  2. 服务器端接收或处理逻辑有误,未正确解析multipart/form-data格式。
  3. 网络传输过程中数据包丢失或损坏,可检查网络稳定性。
  4. 鸿蒙Next的API实现可能存在特定限制或Bug,需查阅官方文档确认。

在HarmonyOS Next中,request.uploadFile 在处理较大文件时出现损坏,通常与文件分片、流处理或网络请求配置有关。以下排查方向供参考:

  1. 检查文件读取方式:确保使用正确的API读取文件,避免在读取过程中截断。对于二进制文件(如PPT),建议使用 fs.openSyncfs.readSync 以二进制模式读取,或直接使用 file 对象(如 picker 返回的 Uri 文件对象)作为 uploadFilefile 参数。

  2. 验证分片上传逻辑:如果自行实现了分片上传,需确认分片大小计算、切片边界处理是否正确。HarmonyOS Next的文件API可能与其他平台存在差异,建议使用系统推荐的分片方法(如 fs.createStream 处理流)。

  3. 排查网络请求超时与缓冲区:检查 requestconnectTimeoutheader 配置,确保服务器支持大文件上传。部分网络库在默认配置下可能限制请求体大小,可尝试调整 timeout 或使用 data 字段分段发送。

  4. 对比服务器接收逻辑:确认服务器端接收文件的代码是否兼容HarmonyOS的上传格式(如 multipart/form-data 边界处理)。建议通过抓包工具(如Charles)对比鸿蒙与安卓的上传请求体,查看数据是否完整。

  5. 使用最新SDK与工具:确保DevEco Studio和HarmonyOS SDK已更新至最新版本,早期版本可能存在文件上传相关的已知问题。

若以上步骤仍无法解决,可尝试简化代码:仅上传纯二进制文件(如图片)测试,以排除PPT文件格式或内容的特定影响。

回到顶部