概要
应用可以将应用文件上传到网络服务器,也可以从网络服务器下载网络资源文件到本地应用文件目录。
上传应用文件
开发者可以使用上传下载模块(ohos.request)的上传接口将本地文件上传。文件上传过程使用系统服务代理完成, 在api12中request.agent.create接口增加了设置代理地址参数,支持用户设置自定义代理地址。
说明
当前上传应用文件功能,仅支持上传应用缓存文件路径(cacheDir)下的文件。
使用上传下载模块,需声明权限
:ohos.permission.INTERNET。
代码讲解
textw.ets
// import http from '@ohos.net.http';
// import util from '@ohos.util';
import fs from '@ohos.file.fs';
import picker from '@ohos.file.picker';
// import systemDateTime from '@ohos.systemDateTime';
import request from '@ohos.request';
import { BusinessError} from '@kit.BasicServicesKit';
@Entry
@Component
struct Textw {
//连接、通讯历史记录
@State msgHistory: string = ''
//上传地址
@State uploadUrl: string = "https://musetransfer.com/"
//要上传的文件
@State uploadFilePath: string = ""
//是否允许上传
@State canUpload: boolean = false
scroller: Scroller = new Scroller()
build() {
Row() {
Column() {
Text("request上传示例")
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
.textAlign(TextAlign.Center)
.padding(10)
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
Text("上传的文件:")
.fontSize(14)
.width(100)
.flexGrow(0)
TextInput({ text: this.uploadFilePath })
.enabled(false)
.width(100)
.fontSize(11)
.flexGrow(1)
Button("选择")
.onClick(() => {
this.selectFile()
})
.width(70)
.fontSize(14)
}
.width('100%')
.padding(10)
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
Text("上传地址:")
.fontSize(14)
.width(80)
.flexGrow(0)
TextInput({ text: this.uploadUrl })
.onChange((value) => {
this.uploadUrl = value
})
.width(110)
.fontSize(11)
.flexGrow(1)
Button("请求")
.onClick(() => {
this.uploadFile()
})
.enabled(this.canUpload)
.width(70)
.fontSize(14)
.flexGrow(0)
}
.width('100%')
.padding(10)
Scroll(this.scroller) {
Text(this.msgHistory)
.textAlign(TextAlign.Start)
.padding(10)
.width('100%')
.backgroundColor(0xeeeeee)
}
.align(Alignment.Top)
.backgroundColor(0xeeeeee)
.height(300)
.flexGrow(1)
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.On)
.scrollBarWidth(20)
}
.width('100%')
.justifyContent(FlexAlign.Start)
.height('100%')
}
.height('100%')
}
//上传文件
async uploadFile() {
let context = getContext(this)
let segments = this.uploadFilePath.split('/')
//文件名称
let fileName = segments[segments.length-1]
//计划复制到的目标路径
let realUri = context.cacheDir + "/" + fileName
//复制选择的文件到沙箱cache文件夹
try {
let file = await fs.open(this.uploadFilePath);
fs.copyFileSync(file.fd, realUri)
} catch (err) {
this.msgHistory += 'err.code : ' + err.code + ', err.message : ' + err.message;
}
let uploadTask: request.UploadTask
let uploadConfig: request.UploadConfig = {
url: this.uploadUrl,
header: { 'Accept': '*/*' },
method: "POST",
files: [{ filename: fileName, name: fileName, uri: `internal://cache/${fileName}`, type: "txt" }],
data: [],
};
try {
request.uploadFile(context, uploadConfig).then((data) => {
uploadTask = data;
uploadTask.on("progress", (size, tot) => {
this.msgHistory += `上传进度:${size}/${tot}\r\n`
})
uploadTask.on("complete", () => {
this.msgHistory += "上传完成\r\n"
console.log('qwert'+'成功')
})
}).catch((e:BusinessError) => {
console.log('失败'+'qwert')
this.msgHistory += "请求失败:" + e.message + "\r\n"
})
} catch (err) {
this.msgHistory += 'err.code : ' + err.code + ', err.message : ' + err.message;
}
}
//选择文件,为简单起见,选择一个不太大的文本文件
selectFile() {
let documentPicker = new picker.DocumentViewPicker();
documentPicker.select().then((result) => {
if (result.length > 0) {
this.uploadFilePath = result[0]
this.msgHistory += "select file: " + this.uploadFilePath + "\r\n";
this.canUpload = true
}
}).catch((e:BusinessError) => {
console.log('失败'+'qwert')
this.msgHistory += 'DocumentViewPicker.select failed ' + e.message + "\r\n";
});
}
}
index.ets
import { picker } from '@kit.CoreFileKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import {FileUpload,File,FormData} from "@ohos/commons-fileupload"
import { log, logError, debug } from "../utils/log"
import * as EntryAbility from '../entryability/EntryAbility'
@Entry
@Component
struct UploadFile {
@StorageProp('urls') urls: string = ''
@State message: string = '文件上传'
@State loadedFileResult: string = "";
fileInfo: Array<File> = [];
fileUpload: FileUpload|ESObject
aboutToAppear() {
this.fileUpload = new FileUpload({
baseUrl: "https://musetransfer.com/",
readTimeout: 60000,
connectTimeout: 60000
})
}
build() {
Column() {
Column() {
Text("第一步:加载文件").fontSize(20).margin({ bottom: 20 })
Row({ space: 10 }) {
Button("icon.png").onClick(() => this.loadFileByResource("icon.png"))
Button("test.txt").onClick(() => this.loadFileByResource("test.txt"))
Button('点我文件上传').onClick((event: ClickEvent) => {
const documentSelectOptions = new picker.DocumentSelectOptions();
// 选择文档的最大数目(可选)
documentSelectOptions.maxSelectNumber = 1;
// 指定选择的文件或者目录路径(可选)
// documentSelectOptions.defaultFilePathUri = "file://docs/storage/Users/currentUser/test";
// 选择文件的后缀类型['后缀类型描述|后缀类型'](可选) 若选择项存在多个后缀名,则每一个后缀名之间用英文逗号进行分隔(可选),后缀类型名不能超过100,选择所有文件:'所有文件(*.*)|.*';
documentSelectOptions.fileSuffixFilters = ['图片(.png, .jpg)|.png,.jpg', '文档|.txt', '视频|.mp4', '.pdf'];
//选择是否对指定文件或目录授权,true为授权,当为true时,defaultFilePathUri为必选参数,拉起文管授权界面;false为非授权,拉起常规文管界面(可选)
documentSelectOptions.authMode = true;
let uris: Array<string> = [];
let context = getContext(this) as common.Context; // 请确保 getContext(this) 返回结果为 UIAbilityContext
// 创建文件选择器实例
const documentViewPicker = new picker.DocumentViewPicker(context);
documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => {
//文件选择成功后,返回被选中文档的uri结果集。
uris = documentSelectResult;
console.info('documentViewPicker.select to file succeed and uris are:' + uris+'qwert');
AppStorage.setOrCreate('urls',uris)
}).catch((err: BusinessError) => {
console.error('qwert'+`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
})
}.padding({ left: 10 })
Text("已加载文件信息:" + this.loadedFileResult).fontSize(20).margin({ top: 10 }).padding({ left: 10 })
}.alignItems(HorizontalAlign.Start).width("100%").height('70%')
Column() {
Text("第二步:上传文件").fontSize(20).margin({ bottom: 20 })
Button("点击上传").onClick(() => this.upload())
}.alignItems(HorizontalAlign.Start).width("100%")
}
.width('100%')
.height("100%")
.padding({ top: 50, bottom: 80 })
.justifyContent(FlexAlign.SpaceBetween)
}
/**
* 通过资源加载文件
* @param fileName
*/
loadFileByResource(fileName: string): void {
EntryAbility.resourceManager.getRawFile(fileName, (error:ESObject, value:ESObject) => {
if (error != null) {
logError(error);
this.loadedFileResult = "加载文件失败..."
return;
}
const file:ESObject = new File();
file.fileName = fileName;
file.fileData = value;
this.fileInfo.push(file);
this.loadedFileResult = this.loadedFileResult += "--" + fileName + " "
})
}
/**
* 上传
*/
upload() {
console.log('qwert'+this.urls)
if (!this.fileInfo) {
logError("当前上传的文件为空,请先加载之后再上传"+'qwert');
return;
}
log('检验通过')
const formData:ESObject = new FormData();
formData.append("id", 1);
this.fileInfo.forEach((v:ESObject) => {
formData.append(v.fileName, v);
})
log("formData实例化完成,准备上传")
this.fileUpload.post("/api/upload", formData).then((res:ESObject) => {
log("this.fileUpload.request 成功---" + JSON.stringify(res)+'qwert')
}).catch((err:ESObject) => {
logError("this.fileUpload.request 失败" + JSON.stringify(err)+'qwert')
})
}
}
同时可以通过select选择器选择文件后保存到沙箱路径方便后面使用
addPicture() {
let pathDir = getContext().filesDir;
const currentTime = Date.now() + 1
// 这些内容在点击保存推出后才会执行
let file = fs.openSync(this.photouri[0], fs.OpenMode.READ_ONLY) //打开文件
let file2 =
fs.openSync(pathDir + `/${currentTime}.jpg`, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) //打开文件
fs.copyFileSync(file.fd, file2.fd)
fs.closeSync(file); //以同步方法关闭文件。
fs.closeSync(file2);
let path = pathDir + `/${currentTime}.jpg`
// let uri=FileUtil.getFilesDirPath()
let uri = fileUri.getUriFromPath(path)
console.log('沙箱地址' + uri)
this.imageUrl = uri
// this.sharePath=currentTime.toString()
}
在语言模型中,编码器和解码器都是由一个个的 Transformer 组件拼接在一起形成的。
技术细节
使用前一定要记得配置网络权限
小结
本篇文章是鸿蒙本地文件拉取-保存至沙箱路径-或者上传到指定地址的文档
详细demo请跳转:select-uploadDown: 本文档是一个本地文件选择上传至指定地址,或保存到沙箱路径的demo (gitee.com)