# 下载文件

从对象存储空间下载文件到小程序本地

本文档适用于微信小程序中使用，如果你不是微信小程序，请移步适合的文档

- [公众号 H5](/miniprogram/dev/wxcloudservice/wxcloudrun/src/development/storage/h5/download)
- [服务端和其他客户端](/miniprogram/dev/wxcloudservice/wxcloudrun/src/development/storage/service/download)

## 请求参数

| 字段 | 说明 | 数据类型 | 默认值 | 必填 |
| --  | -- | -- | -- | --
| fileID   | 云文件 ID | String | - | 是 |
| config   | 配置 | Object | - | 否 |
| success | 成功回调 | | | |
| fail | 失败回调 | | | |
| complete | 结束回调 | | | |

### config 对象定义

| 字段 | 说明 | 数据类型 |
| --  | --   | --     |
| env | 使用的环境 ID，填写后忽略 init 指定的环境 | String |

#### success 返回参数

| 字段 | 说明 | 数据类型 |
| --  | --   | --     |
| tempFilePath | 临时文件路径 | String |
| statusCode | 服务器返回的 HTTP 状态码 | Number |
| errMsg  | 成功为 downloadFile:ok，失败为失败原因 | String |

#### fail 返回参数

| 字段 | 说明 | 数据类型 |
| --  | --   | --     |
| errCode | [错误码](/miniprogram/dev/wxcloudservice/wxcloud/reference/errcode.md) | Number |
| errMsg | 错误信息，格式 downloadFile:fail msg | String |

#### 返回值

如果请求参数中带有 success/fail/complete 回调中的任一个，则会返回一个 [downloadTask](/miniprogram/dev/api/network/download/DownloadTask.md) 对象，通过 [downloadTask](/miniprogram/dev/api/network/download/DownloadTask.md) 对象可监听上传进度变化事件，以及取消上传任务。

## 使用示例

### 1. Callback 风格

```js
wx.cloud.downloadFile({
  fileID: 'cloud://test.png', // 对象存储文件ID，从上传文件接口或者控制台获取
  success: res => {
    console.log(res.tempFilePath)
  },
  fail: err => {
    console.error(err)
  }
})
```

#### 2. Promise 风格

```js
wx.cloud.downloadFile({
  fileID: 'cloud://test.png', // 对象存储文件ID，从上传文件接口或者控制台获取
}).then(res => {
  console.log(res.tempFilePath)
}).catch(error => {
  console.error(err)
})
```

#### 3. 完整示例

在小程序的任何一个页面 js 替换如下代码，`cloud://test.png` 替换成自己存在的文件 `cloudID`

将在页面载入时，会自动启动下载任务

封装的下载函数中 `onCall` 方法参数，可以接收到文件下载进度的回调，可以随时返回 `false` 中断下载任务，返回其他或者不返回则正常下载直到结束。

下载后，调用 `wx.saveFile` 保存文件到本机

``` js
Page({
  async onLoad() {
    const result = await this.downloadFile('cloud://test.png',function(res){
      console.log(`下载进度：${res.progress}%，已下载${res.totalBytesWritten}B，共${res.totalBytesExpectedToWrite}B`)
      // if(res.progress > 50){ // 测试文件下载一半就终止下载
      //   return false
      // }
    })
    wx.saveFile({
      tempFilePath: result.tempFilePath
    }).then(console.log)
  },
  /**
   * 下载微信云托管对象存储到本地
   * @param {*} fileID 对象存储文件ID
   * @param {*} onCall 上传回调，文件上传过程监听，返回false时会中断上传
   */
  downloadFile(fileID, onCall = () => {}) {
    return new Promise((resolve, reject) => {
      const task = wx.cloud.downloadFile({
        fileID,
        success: res => resolve(res),
        fail: e => {
          const info = e.toString()
          if (info.indexOf('abort') != -1) {
            reject(new Error('【文件下载失败】中断下载'))
          } else {
            reject(new Error('【文件下载失败】网络或其他错误'))
          }
        }
      })
      task.onProgressUpdate((res) => {
        if (onCall(res) == false) {
          task.abort()
        }
      })
    })
  }
})
```

## 资源复用

如果是资源复用，需要先进行初始化，初始化过程是异步，需要在业务中加以处理

在小程序 app.js 中粘贴如下代码，记得修改相关的信息，封装 downloadFile 可以参考上面例子，唯一不同点就是 wx.cloud 替换，其他基本一致

``` js
App({
  logger:require('./log.js'),
  async onLaunch() {
    const c1 = new wx.cloud.Cloud({
      resourceAppid: 'wx886699112233', // 环境所属的账号appid
      resourceEnv: 'prod-weruntest', // 微信云托管的环境ID
    })
    await c1.init()
    this.cloud = c1 // 在页面js中，可以使用getApp().cloud
    this.cloud.downloadFile({
      fileID: 'cloud://test.png', // 对象存储文件ID，从上传文件接口或者控制台获取
      success: res => {
        console.log(res.tempFilePath)
      },
      fail: err => {
        console.error(err)
      }
    })
  }
})
```
