当前位置: 首页 > news >正文

做普通网站公司wordpress 维护代码

做普通网站公司,wordpress 维护代码,网站建设投诉去哪里投诉,网站放视频代码一、案例实现 (一) 案例效果截图 (二) 案例运用到的知识点 核心知识点 文件管理能力 #xff1a;该模块为基础文件操作API#xff0c;提供基础文件操作能力#xff0c;包括文件基本管理、文件目录管理、文件信息统计、文件流式读写等常用功能。#xff08;ohos.file.f…一、案例实现 (一) 案例效果截图   (二) 案例运用到的知识点 核心知识点 文件管理能力 该模块为基础文件操作API提供基础文件操作能力包括文件基本管理、文件目录管理、文件信息统计、文件流式读写等常用功能。ohos.file.fs选择器 选择器Picker模块封装了PhotoViewPicker、DocumentViewPicker、AudioViewPicker等API模块提供文件选择与保存能力。ohos.file.picker相册管理模块 该模块提供相册管理模块能力包括创建相册以及访问、修改相册中的媒体数据信息等。ohos.file.photoAccessHelperPhotoViewPicker 图库选择器对象用来支撑选择图片/视频和保存图片/视频等用户场景。DocumentViewPicker 文件选择器对象用来支撑选择和保存各种格式文档。 其他知识点 ArkTS 语言基础V2版状态管理ComponentV2/Local自定义组件自定义构建函数Builder内置组件SaveButton/Tabs/Scroll/Column/Text/TextArea/Button常量与资源分类的访问MVVM模式 (三) 代码结构 ├──entry/src/main/ets // 代码区 │ ├──common │ │ └──utils │ │ ├──Logger.ets // 日志打印类 │ │ ├──PictureSaving.ets // 图片保存方法 │ │ ├──ReadFile.ets // 文件读取方法 │ │ ├──SavingAndSelectUserFile.ets // 用户文件保存与选择方法 │ │ └──WriteFile.ets // 文件写入方法 │ ├──entryability │ │ └──EntryAbility.ets // 程序入口类 │ ├──pages │ │ └──HomePage.ets // 主界面 │ └──view │ ├──ApplicationFileTab.ets // 应用文件功能展示 │ └──PublicFilesTab.ets // 公共文件功能展示 └──entry/src/main/resources // 资源文件目录 (四) 公共文件与资源 本案例涉及到的常量类和工具类代码如下 通用日志类 // entry/src/main/ets/common/utils/Logger.ets import { hilog } from kit.PerformanceAnalysisKitconst LOGGER_PREFIX: string File_Management class Logger {private domain: numberprivate prefix: stringprivate format: string %{public}s, %{public}sconstructor(prefix: string , domain: number 0xFF00) {this.prefix prefixthis.domain domain}debug(...args: string[]): void {hilog.debug(this.domain, this.prefix, this.format, args)}info(...args: string[]): void {hilog.info(this.domain, this.prefix, this.format, args)}warn(...args: string[]): void {hilog.warn(this.domain, this.prefix, this.format, args)}error(...args: string[]): void {hilog.error(this.domain, this.prefix, this.format, args)} }export default new Logger(LOGGER_PREFIX, 0xFF02) 本案例涉及到的资源文件如下 string.json // entry/src/main/resources/base/element/string.json {string: [{name: module_desc,value: 模块描述},{name: EntryAbility_desc,value: description},{name: EntryAbility_label,value: 文件管理},{name: textarea_default,value: 请输入保存至文件的内容},{name: file_content,value: 文件内容},{name: button1,value: 保存至应用沙箱目录},{name: button2,value: 读取保存的文件内容},{name: title,value: 文件管理},{name: bar1,value: 应用文件},{name: bar2,value: 公共文件},{name: select_photo,value: 从图库中选择一张图片展示},{name: textarea_default2,value: 文件内容...},{name: button3,value: 保存test.txt至用户目录},{name: button4,value: 读取test.txt文件内容}] } color.json // entry/src/main/resources/base/element/color.json {color: [{name: start_window_background,value: #FFFFFF},{name: text_color,value: #182431},{name: picture_background,value: #0D182431}] } float.json // entry/src/main/resources/base/element/float.json {float: [{name: default_22,value: 22vp},{name: default_24,value: 24vp},{name: default_294,value: 294vp},{name: default_312,value: 312vp},{name: default_40,value: 40vp},{name: default_16,value: 16vp},{name: default_13,value: 13vp},{name: default_336,value: 336vp},{name: default_8,value: 8vp},{name: default_139,value: 139vp},{name: default_20,value: 20vp},{name: default_100,value: 100vp},{name: default_48,value: 48vp},{name: default_147,value: 147vp},{name: default_10,value: 10vp},{name: default_223,value: 223vp},{name: default_302,value: 302vp},{name: default_213,value: 213vp},{name: default_120,value: 120vp},{name: default_251,value: 251vp},{name: default_41,value: 41vp},{name: default_30,value: 30vp},{name: default_7,value: 7vp},{name: default_360,value: 360vp},{name: default_56,value: 56vp},{name: default_680,value: 680vp},{name: default_200,value: 200vp},{name: default_12,value: 12vp}] } 其他资源请到源码中获取。 (五) 沙箱路径下的文件读写 构建主界面 // entry/src/main/ets/pages/HomePage.ets import { ApplicationFileTab } from ../views/ApplicationFileTabEntry ComponentV2 struct HomePage {build() {Column() {Column() {Text($r(app.string.title)).width($r(app.float.default_312)).height($r(app.float.default_41)).textAlign(TextAlign.Start).fontSize($r(app.float.default_30)).fontFamily(HarmonyHeiTi-Bold).fontColor($r(app.color.text_color)).lineHeight($r(app.float.default_41)).fontWeight(700).margin({top: $r(app.float.default_7),bottom: $r(app.float.default_8),left: $r(app.float.default_24),right: $r(app.float.default_24)})}.width($r(app.float.default_360)).height($r(app.float.default_56))Tabs() {TabContent() {ApplicationFileTab()}.tabBar(new SubTabBarStyle($r(app.string.bar1)).indicator({ marginTop: $r(app.float.default_8) }).labelStyle({ font: { size: $r(app.float.default_16) } }))TabContent() {Scroll() {Text(PublicFilesTab)}.height($r(app.float.default_680))}.height(100%).tabBar(new SubTabBarStyle($r(app.string.bar2)).indicator({marginTop : $r(app.float.default_8)}).labelStyle({font : {size : $r(app.float.default_16)}}))}.barWidth($r(app.float.default_200)).barHeight($r(app.float.default_56)).width(100%)}.backgroundColor($r(app.color.picture_background)).justifyContent(FlexAlign.Center).width(100%)} } 应用文件组件 // entry/src/main/ets/views/ApplicationFileTab.ets import { readFile } from ../common/utils/ReadFile import { writeFile } from ../common/utils/WriteFileComponentV2 export struct ApplicationFileTab {// 用于记录读取的内容。Local message: string // 用于记录文本框中的内容。Local content: string build() {Column() {Text($r(app.string.textarea_default)).width($r(app.float.default_294)).height($r(app.float.default_22)).fontColor($r(app.color.text_color)).fontWeight(500).fontSize($r(app.float.default_16)).fontFamily(HarmonyHeiTi-Medium).lineHeight($r(app.float.default_22)).textAlign(TextAlign.Start).margin({top: $r(app.float.default_13),bottom: $r(app.float.default_13),right: $r(app.float.default_8)})TextArea({ text: this.content }).width($r(app.float.default_336)).height($r(app.float.default_139)).borderRadius($r(app.float.default_24)).backgroundColor($r(app.color.start_window_background)).enableKeyboardOnFocus(false).onChange((value: string) {this.content value})Text($r(app.string.file_content)).width($r(app.float.default_294)).height($r(app.float.default_22)).fontSize($r(app.float.default_16)).lineHeight($r(app.float.default_22)).fontWeight(500).margin({top: $r(app.float.default_13),bottom: $r(app.float.default_13),right: $r(app.float.default_8)})TextArea({ text: this.message }).enableKeyboardOnFocus(false).width($r(app.float.default_336)).height($r(app.float.default_139)).backgroundColor($r(app.color.start_window_background)).borderRadius($r(app.float.default_24))Column() {Button($r(app.string.button1)).width($r(app.float.default_312)).height($r(app.float.default_40))// 写入信息并清空输入内容点击“保存”后清空文本框。.onClick(() {writeFile(this.content)this.content })Button($r(app.string.button2)).width($r(app.float.default_312)).height($r(app.float.default_40)).margin({top: $r(app.float.default_12),bottom: $r(app.float.default_100)}).onClick(() {this.message readFile()})}.width(100%).margin({ top: $r(app.float.default_100) })}.width(100%).height(100%)} } 实现沙箱路径下文件的写入操作 // entry/src/main/ets/common/utils/WriteFile.ets import { fileIo } from kit.CoreFileKit import { common } from kit.AbilityKitlet context getContext(this) as common.UIAbilityContext let filesDir context.filesDir/*** writeFile.* 将内容写入文件* param content 要写入文件的内容*/ export function writeFile(content: string): void {let filePath filesDir /test.txt// 基于文件路径打开文件流let fileStream fileIo.createStreamSync(filePath, w)fileStream.writeSync(content)fileStream.close() } 关键代码说明 首先需要结合context得到想要操作的文件路径。然后对该文件进行写入操作这里使用的是createStreamSync创建文件流的形式。通过文件流的方式可以控制文件的读写方式覆盖写的方式可以使得每次写操作互不影响。 实现沙箱路径下文件的读取操作 // entry/src/main/ets/common/utils/ReadFile.ets import { fileIo } from kit.CoreFileKit import { common } from kit.AbilityKit import { buffer } from kit.ArkTS// 获取应用文件路径 let context getContext(this) as common.UIAbilityContext let filesDir context.filesDir let res: string /*** readFile.* 读取文件内容并返回字符串。* return 字符串。*/ export function readFile(): string {let filePath filesDir /test.txtlet stat fileIo.statSync(filePath)let size stat.sizelet buf new ArrayBuffer(size)// 基于文件路径打开文件流let fileStream fileIo.createStreamSync(filePath, r)// 读取文件流信息fileStream.readSync(buf)// 将读取的信息转换为字符串类型并返回let con buffer.from(buf, 0)res con.toString()fileStream.close()return res } 关键代码说明 与写入类似也通过文件路径去创建文件流进行读取操作。通过statSync获取文件的详细信息进而得到文件内容的大小然后利用文件流将文件内容读取到ArrayBuffer中再将ArrayBuffer转化为string返回即可完成文件的读取操作。 (六) 图库的读取与写入 在主界面引入公共文件组件 // entry/src/main/ets/pages/HomePage.ets // ... import { publicFilesTab } from ../views/PublicFilesTabEntry ComponentV2 struct HomePage {build() {Column() {// ...Tabs() {// ...TabContent() {Scroll() {publicFilesTab()}// ...}// ...}// ...}// ...} } 构建公共文件组件实现保存图片到图库 // entry/src/main/ets/views/PublicFilesTab.ets import { photoAccessHelper } from kit.MediaLibraryKit import { fileIo } from kit.CoreFileKit import Logger from ../common/utils/Logger import { photoPickerGetUri } from ../common/utils/PictureSavingComponentV2 export struct publicFilesTab {Local picture: string Local flag: Boolean falseLocal message: string Local content: string Local isInput: Boolean false// 设置安全控件的按钮属性Local saveButtonOptions: SaveButtonOptions {icon: SaveIconStyle.FULL_FILLED,text: SaveDescription.SAVE_IMAGE,buttonType: ButtonType.Capsule}build() {Column() {Column() {Image($r(app.media.img)).borderRadius($r(app.float.default_24)).width($r(app.float.default_312)).height($r(app.float.default_147))// 创建安全控件按钮SaveButton(this.saveButtonOptions).onClick(async (event, result: SaveButtonOnClickResult) {if (result SaveButtonOnClickResult.SUCCESS) {try {Logger.info(createAsset 成功, event: event)let context getContext()let phAccessHelper photoAccessHelper.getPhotoAccessHelper(context)// 创建媒体文件let uri await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, jpg)Logger.info(createAsset 成功, uri: uri)// 打开创建的媒体文件读取本地文件并转换为 ArrayBuffer便于写入let file await fileIo.open(uri, fileIo.OpenMode.READ_WRITE)let buffer getContext(this).resourceManager.getMediaContentSync($r(app.media.img).id)// 将读取的 ArrayBuffer 写入新的媒体文件let writeLen await fileIo.write(file.fd, buffer.buffer)Logger.info(写入成功, 长度 writeLen)await fileIo.close(file)} catch (err) {Logger.error(createAsset 失败, message , err)}} else {Logger.error(SaveButtonOnClickResult createAsset 失败)}})}.margin({ bottom: $r(app.float.default_10) }).width($r(app.float.default_336)).height($r(app.float.default_223)).borderRadius($r(app.float.default_24)).justifyContent(FlexAlign.SpaceAround).backgroundColor($r(app.color.start_window_background))Column() {Text($r(app.string.select_photo)).width($r(app.float.default_302)).height($r(app.float.default_48)).lineHeight($r(app.float.default_22)).fontFamily(HarmonyHeiTi-Medium).fontSize($r(app.float.default_16)).fontWeight(500).textAlign(TextAlign.Start).fontColor($r(app.color.text_color))Column() {if (!this.flag) {Image($r(app.media.ic_folder_add2)).width($r(app.float.default_24)).height($r(app.float.default_24)).objectFit(ImageFit.Contain)} else {Image(this.picture).width(100%).height(100%).borderRadius($r(app.float.default_24))}}.width($r(app.float.default_312)).height($r(app.float.default_147)).borderRadius($r(app.float.default_16)).backgroundColor($r(app.color.picture_background)).onClick(async () {await photoPickerGetUri().then(value {this.flag truethis.picture value})}).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}.margin({ bottom: $r(app.float.default_10) }).backgroundColor($r(app.color.start_window_background)).width($r(app.float.default_336)).height($r(app.float.default_213)).borderRadius($r(app.float.default_24))}.width(100%)} } 关键代码说明 首先需要在图库中创建媒体资源随后将图片读取转化为ArrayBuffer最后再将该内容写入在图库中创建的媒体资源中。createAsset方法会返回在图库中新建的媒体资源的uri只不过此时还是没有内容的空文件然后需要将本地图片文件的内容读取出来并写入该空文件即可完成图片保存到图库的操作。 从图库中选择图片进行展示 // entry/src/main/ets/common/utils/PictureSaving.ets import { photoAccessHelper } from kit.MediaLibraryKit import { BusinessError } from kit.BasicServicesKit import Logger from ./Logger// 定义 URI 数组用于接收 PhotoViewPicker 选择图片后返回的 URI。 let uris: Arraystring []/*** photoPickerGetUri.* 根据 PhotoViewPicker 的 select 方法返回所选文件的 URI。* return Promisestring.*/ export async function photoPickerGetUri(): Promisestring {try {let PhotoSelectOptions new photoAccessHelper.PhotoSelectOptions()PhotoSelectOptions.MIMEType photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPEPhotoSelectOptions.maxSelectNumber 1let photoPicker new photoAccessHelper.PhotoViewPicker()await photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) {Logger.info(PhotoViewPicker.select 成功, 返回的 PhotoSelectResult uri: JSON.stringify(PhotoSelectResult))uris PhotoSelectResult.photoUris}).catch((err: BusinessError) {Logger.error(PhotoViewPicker.select 失败, 错误信息: JSON.stringify(err))})} catch (error) {let err error as BusinessErrorLogger.error(PhotoViewPicker 失败, 错误信息: err.message)}return uris[0].toString() } 关键代码说明 调用PhotoViewPicker的select方法来得到被选择图片的uri即可完成读取图库中图片的信息。 (七) 用户目录的文件读写 // entry/src/main/ets/common/utils/SavingAndSelectUserFile.ets import { BusinessError } from kit.BasicServicesKit import { picker, fileIo } from kit.CoreFileKit import { buffer } from kit.ArkTS import Logger from ./Loggerlet uri: string // 获取应用文件路径let message: string /*** saveToUser.* 将内容保存到用户目录文件中* param content 要保存到用户目录文件中的内容*/ export async function saveToUser(content: string) {try {let DocumentSaveOptions new picker.DocumentSaveOptions()DocumentSaveOptions.newFileNames [test.txt]let documentPicker new picker.DocumentViewPicker()documentPicker.save(DocumentSaveOptions).then((DocumentSaveResult: Arraystring) {Logger.info(DocumentViewPicker.save 成功返回的 uri: JSON.stringify(DocumentSaveResult))uri DocumentSaveResult[0]let file fileIo.openSync(uri, fileIo.OpenMode.READ_WRITE)// 根据文件路径打开文件流。fileIo.writeSync(file.fd, content)}).catch((err: BusinessError) {Logger.error(DocumentViewPicker.save 失败错误信息: JSON.stringify(err))})} catch (error) {let err: BusinessError error as BusinessErrorLogger.error(DocumentViewPicker 失败错误信息: err.message)} }/*** readUserFile.* 读取用户目录文件中的内容。* return Promisestring.*/ export async function readUserFile(): Promisestring {try {let DocumentSelectOptions new picker.DocumentSelectOptions()let documentPicker new picker.DocumentViewPicker()await documentPicker.select(DocumentSelectOptions).then((DocumentSelectResult: Arraystring) {Logger.info(DocumentViewPicker.select 成功返回的 uri: JSON.stringify(DocumentSelectResult))uri DocumentSelectResult[0]let file fileIo.openSync(uri, fileIo.OpenMode.READ_WRITE)let stat fileIo.statSync(file.fd)let size stat.sizelet buf new ArrayBuffer(size)fileIo.readSync(file.fd, buf)let con buffer.from(buf, 0)message con.toString()Logger.info(DocumentViewPicker.select 成功读取的内容: message)return message}).catch((err: BusinessError) {Logger.error(DocumentViewPicker.select 失败错误信息: JSON.stringify(err))})} catch (error) {let err error as BusinessErrorLogger.error(DocumentViewPicker.select 失败错误信息: err.message)}return message } 关键代码说明 在DocumentViewPicker提供的save方法的帮助下可以向用户目录下创建一个文件并返回它的uri。DocumentViewPicker提供的select方法可以选择想要访问的文件并返回其uri。获取到uri后即可完成对文件的读取并将信息返回的操作。 二、文件管理知识点 Core File Kit文件基础服务为开发者提供统一的文件访问和管理能力涵盖应用文件和用户文件帮助用户高效地查找、管理、备份各类文件满足多样化的文件操作需求。 在文件分类上Core File Kit将文件划分为三类应用文件如安装包、资源、缓存等由应用拥有和管理用户文件如图片、视频、文档等由登录用户所有系统文件包括系统资源、设备文件等由系统统一管理开发者无需操作。按文件存储位置分为本地文件系统本地设备或外置设备和分布式文件系统支持跨设备访问。 Core File Kit支持对应用文件进行查看、创建、读写、删除、复制、移动、获取属性等操作支持将应用文件上传至服务器或从服务器下载资源支持查询应用及文件系统的空间使用情况支持通过URI或文件描述符方式实现跨应用文件分享支持配置应用数据的备份与恢复同时提供统一的用户文件访问接口便于用户文件的选择与保存还支持在多设备间进行文件访问和传输。 亮点方面Core File Kit采用沙箱隔离机制为每个应用提供专属的文件目录空间确保文件的隔离性与安全性。通过分享机制开发者可安全、高效地实现应用间文件共享确保数据一致性与传输安全是构建HarmonyOS文件能力的基础组件之一。 (一) 应用文件 应用文件的所有者为应用包括应用安装文件、应用资源文件、应用缓存文件等。 1. 应用沙箱目录 应用沙箱是一种以安全防护为目的的隔离机制避免数据受到恶意路径穿越访问。在这种沙箱的保护机制下应用可见的目录范围即为“应用沙箱目录”。 对于每个应用系统会在内部存储空间映射出一个专属的“应用沙箱目录”它是“应用文件目录”与一部分系统文件应用运行必需的少量系统文件所在的目录组成的集合。应用沙箱限制了应用可见的数据范围。在“应用沙箱目录”中应用仅能看到自己的应用文件以及少量的系统文件应用运行必需的少量系统文件。因此本应用的文件也不为其他应用可见从而保护了应用文件的安全。应用可以在“应用文件目录”下保存和处理自己的应用文件系统文件及其目录对于应用是只读的而应用若需访问用户文件则需要通过特定API同时经过用户的相应授权才能进行。 下图展示了应用沙箱下应用可访问的文件范围和方式。 2. 应用文件访问 应用需要对应用文件目录下的应用文件进行查看、创建、读写、删除、移动、复制、获取属性等访问操作下面介绍具体方法。 接口说明 开发者通过基础文件操作接口ohos.file.fs实现应用文件访问能力主要功能如下表所示。 接口名 功能 接口类型 支持同步 支持异步 access 检查文件是否存在 方法 √ √ close 关闭文件 方法 √ √ copyFile 复制文件 方法 √ √ createStream 基于文件路径打开文件流 方法 √ √ listFile 列出文件夹下所有文件名 方法 √ √ mkdir 创建目录 方法 √ √ moveFile 移动文件 方法 √ √ open 打开文件 方法 √ √ read 从文件读取数据 方法 √ √ rename 重命名文件或文件夹 方法 √ √ rmdir 删除整个目录 方法 √ √ stat 获取文件详细属性信息 方法 √ √ unlink 删除单个文件 方法 √ √ write 将数据写入文件 方法 √ √ Stream.close 关闭文件流 方法 √ √ Stream.flush 刷新文件流 方法 √ √ Stream.write 将数据写入流文件 方法 √ √ Stream.read 从流文件读取数据 方法 √ √ File.fd 获取文件描述符 属性 - - OpenMode 设置文件打开标签 属性 - - Filter 设置文件过滤配置项 类型 - - 注意使用基础文件操作接口时耗时较长的操作例如read、write等建议使用异步接口避免应用崩溃。 开发示例 在对应用文件开始访问前开发者需要获取应用文件路径。 新建并读写一个文件 以下示例代码演示了如何新建一个文件并对其读写。 import { fileIo as fs, ReadOptions } from kit.CoreFileKit import { common } from kit.AbilityKit import { buffer } from kit.ArkTS// 获取应用文件路径 let context getContext(this) as common.UIAbilityContext let filesDir context.filesDirfunction createFile(): void {// 文件不存在时创建并打开文件文件存在时打开文件let file fs.openSync(filesDir /test.txt, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)// 写入一段内容至文件let writeLen fs.writeSync(file.fd, Try to write str.)console.info(The length of str is: writeLen)// 创建一个大小为1024字节的ArrayBuffer对象用于存储从文件中读取的数据let arrayBuffer new ArrayBuffer(1024)// 设置读取的偏移量和长度let readOptions: ReadOptions {offset: 0,length: arrayBuffer.byteLength}// 读取文件内容到ArrayBuffer对象中并返回实际读取的字节数let readLen fs.readSync(file.fd, arrayBuffer, readOptions)// 将ArrayBuffer对象转换为Buffer对象并转换为字符串输出let buf buffer.from(arrayBuffer, 0, readLen)console.info(the content of file: buf.toString())// 关闭文件fs.closeSync(file) } 读取文件内容并写入到另一个文件 以下示例代码演示了如何从一个文件读写内容到另一个文件。 import { fileIo as fs, ReadOptions, WriteOptions } from kit.CoreFileKit import { common } from kit.AbilityKit// 获取应用文件路径 let context getContext(this) as common.UIAbilityContext let filesDir context.filesDirfunction readWriteFile(): void {// 打开文件let srcFile fs.openSync(filesDir /test.txt, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)let destFile fs.openSync(filesDir /destFile.txt, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)// 读取源文件内容并写入至目的文件let bufSize 4096let readSize 0let buf new ArrayBuffer(bufSize)let readOptions: ReadOptions {offset: readSize,length: bufSize}let readLen fs.readSync(srcFile.fd, buf, readOptions)while (readLen 0) {readSize readLenlet writeOptions: WriteOptions {length: readLen}fs.writeSync(destFile.fd, buf, writeOptions)readOptions.offset readSizereadLen fs.readSync(srcFile.fd, buf, readOptions)}// 关闭文件fs.closeSync(srcFile)fs.closeSync(destFile) } 使用读写接口时需注意可选项参数offset的设置。对于已存在且读写过的文件文件偏移指针默认在上次读写操作的终止位置。 以流的形式读写文件 以下示例代码演示了如何使用流接口读取test.txt的文件内容并写入到destFile.txt文件中。 import { fileIo as fs, ReadOptions } from kit.CoreFileKit import { common } from kit.AbilityKit// 获取应用文件路径 let context getContext(this) as common.UIAbilityContext let filesDir context.filesDirasync function readWriteFileWithStream(): Promisevoid {// 创建并打开输入文件流let inputStream fs.createStreamSync(filesDir /test.txt, r)// 创建并打开输出文件流let outputStream fs.createStreamSync(filesDir /destFile.txt, w)let bufSize 4096let readSize 0let buf new ArrayBuffer(bufSize)let readOptions: ReadOptions {offset: readSize,length: bufSize}// 以流的形式读取源文件内容并写入到目标文件let readLen await inputStream.read(buf, readOptions)readSize readLenwhile (readLen 0) {const writeBuf readLen bufSize ? buf.slice(0, readLen) : bufawait outputStream.write(writeBuf)readOptions.offset readSizereadLen await inputStream.read(buf, readOptions)readSize readLen}// 关闭文件流inputStream.closeSync()outputStream.closeSync() } 使用流接口时需注意流的及时关闭。同时流的异步接口应严格遵循异步接口使用规范避免同步、异步接口混用。流接口不支持并发读写。 查看文件列表 以下示例代码演示了如何查看文件列表。 import { fileIo as fs, Filter, ListFileOptions } from kit.CoreFileKit import { common } from kit.AbilityKit// 获取应用文件路径 let context getContext(this) as common.UIAbilityContext let filesDir context.filesDir// 查看文件列表 function getListFile(): void {let listFileOption: ListFileOptions {recursion: false,listNum: 0,filter: {suffix: [.png, .jpg, .txt],displayName: [test*],fileSizeOver: 0,lastModifiedAfter: new Date(0).getTime()}}let files fs.listFileSync(filesDir, listFileOption)for (let i 0; i files.length; i) {console.info(The name of file: ${files[i]})} } 使用文件流 以下示例代码演示了如何使用文件可读流文件可写流。 import { fileIo as fs } from kit.CoreFileKit import { common } from kit.AbilityKitlet context getContext(this) as common.UIAbilityContext let filesDir context.filesDirfunction copyFileWithReadable(): void {// 创建文件可读流const rs fs.createReadStream(${filesDir}/read.txt)// 创建文件可写流const ws fs.createWriteStream(${filesDir}/write.txt)// 暂停模式拷贝文件。在拷贝数据时将原始数据暂停然后将数据复制到另一个位置// 适用于对数据完整性和一致性要求较高的场景rs.on(readable, () {const data rs.read()if (!data) {return}ws.write(data)}) }function copyFileWithData(): void {// 创建文件可读流const rs fs.createReadStream(${filesDir}/read.txt)// 创建文件可写流const ws fs.createWriteStream(${filesDir}/write.txt)// 流动模式拷贝文件。数据的读取和写入是同时进行的不需要暂停原始数据的访问// 适用于对数据实时性要求较高的场景rs.on(data, (emitData) {const data emitData?.dataif (!data) {return}ws.write(data as Uint8Array)}) } 使用文件哈希流 哈希流是一种数据传输和存储技术可以将任意长度的数据转换为固定长度的哈希值来验证数据的完整性和一致性。以下代码演示了如何使用文件哈希处理接口ohos.file.hash来处理文件哈希流。 import { fileIo as fs } from kit.CoreFileKit import { hash } from kit.CoreFileKit import { common } from kit.AbilityKit// 获取应用文件路径 let context getContext(this) as common.UIAbilityContext let filesDir context.filesDirfunction hashFileWithStream() {const filePath ${filesDir}/test.txt// 创建文件可读流const rs fs.createReadStream(filePath)// 创建哈希流const hs hash.createHash(sha256)rs.on(data, (emitData) {const data emitData?.datahs.update(new Uint8Array(data?.split().map((x: string) x.charCodeAt(0))).buffer)})rs.on(close, async () {const hashResult hs.digest()const fileHash await hash.hash(filePath, sha256)console.info(hashResult: ${hashResult}, fileHash: ${fileHash})}) } (二) 用户文件 用户文件是指登录到该终端设备的用户所拥有的文件包括用户私有的图片、视频、音频、文档等 1. 用户文件uri 用户文件uri是文件的唯一标识在对用户文件进行访问与修改等操作时往往都会使用到uri不建议开发者解析uri中的片段用于业务代码开发。 uri类型可以归纳为文档类uri和媒体文件uri两类 文档类uri由picker拉起文件管理器选择或保存返回以及通过fileAccess模块获取。媒体文件uri由picker通过拉起图库选择图片或者视频返回通过photoAccessHelper模块获取图片或者视频文件的uri以及通过userFileManager模块获取图片、视频或者音频文件的uri。 2. 选择用户文件 用户需要分享文件、保存图片、视频等用户文件时开发者可以通过系统预置的文件选择器FilePicker实现该能力。通过Picker访问相关文件将拉起对应的应用引导用户完成界面操作接口本身无需申请权限。picker获取的uri只具有临时权限获取持久化权限需要通过FilePicker设置永久授权方式获取。 根据用户文件的常见类型选择器FilePicker分别提供以下选项 PhotoViewPicker适用于图片或视频类型文件的选择与保存。DocumentViewPicker适用于文件类型文件的选择与保存。DocumentViewPicker对接的选择资源来自于FilePicker, 负责文件类型的资源管理文件类型不区分后缀比如浏览器下载的图片、文档等都属于文件类型。AudioViewPicker适用于音频类型文件的选择与保存。AudioViewPicker目前对接的选择资源来自于FilePicker。 选择图片或视频类文件 图库选择器对象用来支撑选择图片/视频等用户场景。在使用前需要先创建PhotoViewPicker实例。 let photoPicker new photoAccessHelper.PhotoViewPicker() 用法一 select(option?: PhotoSelectOptions) : PromisePhotoSelectResult 通过选择模式拉起photoPicker界面用户可以选择一个或多个图片/视频。接口采用promise异步返回形式传入可选参数PhotoSelectOptions对象返回PhotoSelectResult对象。示例如下 import { BusinessError } from kit.BasicServicesKit async function example01() {try {let PhotoSelectOptions new photoAccessHelper.PhotoSelectOptions()PhotoSelectOptions.MIMEType photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;PhotoSelectOptions.maxSelectNumber 5let photoPicker new photoAccessHelper.PhotoViewPicker()photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) {console.info(PhotoViewPicker.select successfully, PhotoSelectResult uri: JSON.stringify(PhotoSelectResult))}).catch((err: BusinessError) {console.error(PhotoViewPicker.select failed with err: ${err.code}, ${err.message})})} catch (error) {let err: BusinessError error as BusinessError;console.error(PhotoViewPicker failed with err: ${err.code}, ${err.message})} } 用法二 select(option: PhotoSelectOptions, callback: AsyncCallbackPhotoSelectResult ): void 通过选择模式拉起photoPicker界面用户可以选择一个或多个图片/视频。接口采用callback异步返回形式传入参数PhotoSelectOptions对象返回PhotoSelectResult对象。示例如下 import { BusinessError } from kit.BasicServicesKit async function example02() {try {let PhotoSelectOptions new photoAccessHelper.PhotoSelectOptions()PhotoSelectOptions.MIMEType photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPEPhotoSelectOptions.maxSelectNumber 5let photoPicker new photoAccessHelper.PhotoViewPicker();photoPicker.select(PhotoSelectOptions, (err: BusinessError, PhotoSelectResult: photoAccessHelper.PhotoSelectResult) {if (err) {console.error(PhotoViewPicker.select failed with err: ${err.code}, ${err.message})return}console.info(PhotoViewPicker.select successfully,PhotoSelectResult uri: JSON.stringify(PhotoSelectResult));})} catch (error) {let err: BusinessError error as BusinessError;console.error(PhotoViewPicker failed with err: ${err.code}, ${err.message});} } 用法三 select(callback: AsyncCallbackPhotoSelectResult) : void 通过选择模式拉起photoPicker界面用户可以选择一个或多个图片/视频。接口采用callback异步返回形式返回PhotoSelectResult对象。示例如下 import { BusinessError } from kit.BasicServicesKit async function example03() {try {let photoPicker new photoAccessHelper.PhotoViewPicker()photoPicker.select((err: BusinessError, PhotoSelectResult: photoAccessHelper.PhotoSelectResult) {if (err) {console.error(PhotoViewPicker.select failed with err: ${err.code}, ${err.message})return}console.info(PhotoViewPicker.select successfully,PhotoSelectResult uri: JSON.stringify(PhotoSelectResult))})} catch (error) {let err: BusinessError error as BusinessErrorconsole.error(PhotoViewPicker failed with err: ${err.code}, ${err.message})} } 选择文档类文件 导入选择器模块和基础文件API模块。 import { picker } from kit.CoreFileKit import { fileIo as fs } from kit.CoreFileKit import { common } from kit.AbilityKit import { BusinessError } from kit.BasicServicesKit 创建文件类型、文件选择选项实例。 const documentSelectOptions new picker.DocumentSelectOptions() // 选择文档的最大数目可选。 documentSelectOptions.maxSelectNumber 5 // 指定选择的文件或者目录路径可选。 documentSelectOptions.defaultFilePathUri file://docs/storage/Users/currentUser/test // 选择文件的后缀类型[后缀类型描述|后缀类型]可选 若选择项存在多个后缀名 // 则每一个后缀名之间用英文逗号进行分隔可选后缀类型名不能超过100, // 选择所有文件所有文件(*.*)|.*。 documentSelectOptions.fileSuffixFilters [图片(.png, .jpg)|.png,.jpg, 文档|.txt, 视频|.mp4, .pdf] // 选择是否对指定文件或目录授权true为授权当为true时defaultFilePathUri为必选参数 // 拉起文管授权界面false为非授权默认为false拉起常规文管界面可选仅支持2in1设备。 documentSelectOptions.authMode false 创建文件选择器DocumentViewPicker实例。调用select()接口拉起FilePicker应用界面进行文件选择。 let uris: Arraystring [] // 请确保 getContext(this) 返回结果为 UIAbilityContext let context getContext(this) as common.Context // 创建文件选择器实例 const documentViewPicker new picker.DocumentViewPicker(context); documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Arraystring) {//文件选择成功后返回被选中文档的uri结果集。uris documentSelectResultconsole.info(documentViewPicker.select to file succeed and uris are: uris)}).catch((err: BusinessError) {console.error(Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message})}) 待界面从FilePicker返回后使用基础文件API的fs.openSync接口通过uri打开这个文件得到文件描述符(fd)。 let uri: string //这里需要注意接口权限参数是fs.OpenMode.READ_ONLY。 let file fs.openSync(uri, fs.OpenMode.READ_ONLY) console.info(file fd: file.fd) 通过fd使用fs.readSync接口读取这个文件内的数据。 let buffer new ArrayBuffer(4096) let readLen fs.readSync(file.fd, buffer) console.info(readSync data to file succeed and buffer size is: readLen) //读取完成后关闭fd。 fs.closeSync(file) 选择音频类文件 导入选择器模块和基础文件API模块。 import { picker } from kit.CoreFileKit import { fileIo as fs } from kit.CoreFileKit import { BusinessError } from kit.BasicServicesKit import { common } from kit.AbilityKit 创建音频类型文件选择选项实例。 const audioSelectOptions new picker.AudioSelectOptions() 创建音频选择器AudioViewPicker实例。调用select()接口拉起FilePicker应用界面进行文件选择。 let uris: string // 请确保 getContext(this) 返回结果为 UIAbilityContext let context getContext(this) as common.Context const audioViewPicker new picker.AudioViewPicker(context) audioViewPicker.select(audioSelectOptions).then((audioSelectResult: Arraystring) {//文件选择成功后返回被选中音频的uri结果集。uris audioSelectResult[0]console.info(audioViewPicker.select to file succeed and uri is: uris)}).catch((err: BusinessError) {console.error(Invoke audioViewPicker.select failed code is ${err.code}, message is ${err.message})}) 待界面从FilePicker返回后可以使用基础文件API的fs.openSync接口通过uri打开这个文件得到文件描述符(fd)。 let uri: string //这里需要注意接口权限参数是fs.OpenMode.READ_ONLY。 let file fs.openSync(uri, fs.OpenMode.READ_ONLY) console.info(file fd: file.fd) 通过fd可以使用基础文件API的fs.readSync接口读取这个文件内的数据。 let buffer new ArrayBuffer(4096) let readLen fs.readSync(file.fd, buffer) console.info(readSync data to file succeed and buffer size is: readLen) //读取完成后关闭fd。 fs.closeSync(file) 3. 保存用户文件 在从网络下载文件到本地或将已有用户文件另存为新的文件路径等场景下需要使用FilePicker提供的保存用户文件的能力。 保存图片或视频类文件 当用户需要保存图片、视频等用户文件到图库时无需在应用中申请相册管理模块权限ohos.permission.WRITE_IMAGEVIDEO应用可以通过安全控件或授权弹窗的方式将用户指定的媒体资源保存到图库中。 (1) 使用安全控件保存媒体库资源 下面以使用安全控件创建一张图片资源为例。开发步骤如下 设置安全控件按钮属性。创建安全控件按钮。调用MediaAssetChangeRequest.createImageAssetRequest和PhotoAccessHelper.applyChanges接口创建图片资源。 import { photoAccessHelper } from kit.MediaLibraryKitEntry ComponentV2 struct Index {saveButtonOptions: SaveButtonOptions {icon: SaveIconStyle.FULL_FILLED,text: SaveDescription.SAVE_IMAGE,buttonType: ButtonType.Capsule} // 设置安全控件按钮属性build() {Column() {SaveButton(this.saveButtonOptions) // 创建安全控件按钮.onClick(async (event, result: SaveButtonOnClickResult) {if (result SaveButtonOnClickResult.SUCCESS) {try {let context getContext()let phAccessHelper photoAccessHelper.getPhotoAccessHelper(context)// 需要确保fileUri对应的资源存在let fileUri file://com.example.temptest/data/storage /el2/base/haps/entry/files/test.jpg;let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUri)await phAccessHelper.applyChanges(assetChangeRequest)console.info(createAsset successfully, uri: assetChangeRequest.getAsset().uri)} catch (err) {console.error(create asset failed with error: ${err.code}, ${err.message})}} else {console.error(SaveButtonOnClickResult create asset failed)}})}.width(100%)} } 除了上述通过fileUri从应用沙箱指定资源内容的方式开发者还可以通过ArrayBuffer的方式添加资源内容。 (2) 使用弹窗授权保存媒体库资源 下面以弹窗授权的方式保存一张图片资源为例。开发步骤如下 指定待保存到媒体库的位于应用沙箱的应用文件图片uri。指定待保存照片的创建选项包括文件后缀和照片类型标题和照片子类型可选。调用showAssetsCreationDialog基于弹窗授权的方式获取的目标媒体文件uri。将来源于应用沙箱的照片内容写入媒体库的目标uri。 import { photoAccessHelper } from kit.MediaLibraryKit import { fileIo } from kit.CoreFileKitlet context getContext(this) let phAccessHelper photoAccessHelper.getPhotoAccessHelper(context)async function example() {try {// 指定待保存到媒体库的位于应用沙箱的图片urilet srcFileUri file://com.example.temptest/data/storage/ el2/base/haps/entry/files/test.jpglet srcFileUris: Arraystring [srcFileUri]// 指定待保存照片的创建选项包括文件后缀和照片类型标题和照片子类型可选let photoCreationConfigs: ArrayphotoAccessHelper.PhotoCreationConfig [{title: test, // 可选fileNameExtension: jpg,photoType: photoAccessHelper.PhotoType.IMAGE,subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选}]// 基于弹窗授权的方式获取媒体库的目标urilet desFileUris: Arraystring await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs)// 将来源于应用沙箱的照片内容写入媒体库的目标urilet desFile: fileIo.File await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY)let srcFile: fileIo.File await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY)await fileIo.copyFile(srcFile.fd, desFile.fd)fileIo.closeSync(srcFile)fileIo.closeSync(desFile)console.info(create asset by dialog successfully)} catch (err) {console.error(failed to create asset by dialog successfully errCode is: ${err.code}, ${err.message})} } 保存文档类文件 模块导入。 import { picker } from kit.CoreFileKit import { fileIo as fs } from kit.CoreFileKit import { BusinessError } from kit.BasicServicesKit import { common } from kit.AbilityKit 配置保存选项。 // 创建文件管理器选项实例。 const documentSaveOptions new picker.DocumentSaveOptions() // 保存文件名可选。 默认为空。 documentSaveOptions.newFileNames [DocumentViewPicker01.txt] // 保存文件类型[后缀类型描述|后缀类型],选择所有文件所有文件(*.*)|.*可选 // 如果选择项存在多个后缀最大限制100个过滤后缀默认选择第一个。 // 如果不传该参数默认无过滤后缀。 documentSaveOptions.fileSuffixChoices [文档|.txt, .pdf] 创建文件选择器DocumentViewPicker实例。调用save()接口拉起FilePicker界面进行文件保存。 let uris: Arraystring [] // 请确保 getContext(this) 返回结果为 UIAbilityContext let context getContext(this) as common.Context const documentViewPicker new picker.DocumentViewPicker(context) documentViewPicker.save(documentSaveOptions).then((documentSaveResult: Arraystring) {uris documentSaveResultconsole.info(documentViewPicker.save to file succeed and uris are: uris)}).catch((err: BusinessError) {console.error(Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message})}) 待界面从FilePicker返回后使用基础文件API的fs.openSync接口通过URI打开这个文件得到文件描述符(fd)。 const uri //这里需要注意接口权限参数是fs.OpenMode.READ_WRITE。 let file fs.openSync(uri, fs.OpenMode.READ_WRITE) console.info(file fd: file.fd) 通过(fd)使用基础文件API的fs.writeSync接口对这个文件进行编辑修改编辑修改完成后关闭(fd)。 let writeLen: number fs.writeSync(file.fd, hello, world) console.info(write data to file succeed and size is: writeLen) fs.closeSync(file) 保存音频类文件 模块导入。 import { picker } from kit.CoreFileKit import { fileIo as fs } from kit.CoreFileKit import { BusinessError } from kit.BasicServicesKit import { common } from kit.AbilityKit 配置保存选项。 const audioSaveOptions new picker.AudioSaveOptions() // 保存文件名可选 audioSaveOptions.newFileNames [AudioViewPicker01.mp3] 创建音频选择器AudioViewPicker实例。调用save()接口拉起FilePicker界面进行文件保存。 let uri: string // 请确保 getContext(this) 返回结果为 UIAbilityContext let context getContext(this) as common.Context const audioViewPicker new picker.AudioViewPicker(context); audioViewPicker.save(audioSaveOptions).then((audioSelectResult: Arraystring) {uri audioSelectResult[0]console.info(audioViewPicker.save to file succeed and uri is: uri)}).catch((err: BusinessError) {console.error(Invoke audioViewPicker.save failed, code is ${err.code}, message is ${err.message})}) 待界面从FilePicker返回后可以使用基础文件API的fs.openSync接口通过URI打开这个文件得到文件描述符(fd)。 //这里需要注意接口权限参数是fileIo.OpenMode.READ_WRITE。 let file fs.openSync(uri, fs.OpenMode.READ_WRITE) console.info(file fd: file.fd) 通过(fd)使用基础文件API的fs.writeSync接口对这个文件进行编辑修改编辑修改完成后关闭(fd)。 let writeLen fs.writeSync(file.fd, hello, world) console.info(write data to file succeed and size is: writeLen) fs.closeSync(file) DOWNLOAD模式保存文件 该模式具备自动在 Download/包名/ 路径创建目录、跳过文件选择界面直接保存文件、并返回具备持久化权限的URI供用户创建文件的能力。 模块导入。 import { fileUri, picker } from kit.CoreFileKit import { fileIo as fs } from kit.CoreFileKit import { BusinessError } from kit.BasicServicesKit import { common } from kit.AbilityKit 配置下载模式。 const documentSaveOptions new picker.DocumentSaveOptions() // 配置保存的模式为DOWNLOAD若配置了DOWNLOAD模式 // 此时配置的其他documentSaveOptions参数将不会生效。 documentSaveOptions.pickerMode picker.DocumentPickerMode.DOWNLOAD 保存到下载目录。 let uri: string // 请确保 getContext(this) 返回结果为 UIAbilityContext let context getContext(this) as common.Context const documentViewPicker new picker.DocumentViewPiker(context) const documentSaveOptions new picker.DocumentSaveOptions() documentSaveOptions.pickerMode picker.DocumentPickerMode.DOWNLOAD; documentViewPicker.save(documentSaveOptions ).then((documentSaveResult: Arraystring) {uri documentSaveResult[0];console.info(documentViewPicker.save succeed and uri is: uri)const testFilePath new fileUri.FileUri(uri /test.txt).pathconst file fs.openSync(testFilePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)fs.writeSync(file.fd, Hello HarmonyOS)fs.closeSync(file.fd);}).catch((err: BusinessError) {console.error(Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message})})
文章转载自:
http://www.morning.plchy.cn.gov.cn.plchy.cn
http://www.morning.zpqk.cn.gov.cn.zpqk.cn
http://www.morning.wfdlz.cn.gov.cn.wfdlz.cn
http://www.morning.hhfqk.cn.gov.cn.hhfqk.cn
http://www.morning.kfbth.cn.gov.cn.kfbth.cn
http://www.morning.stmkm.cn.gov.cn.stmkm.cn
http://www.morning.gwhjy.cn.gov.cn.gwhjy.cn
http://www.morning.nppml.cn.gov.cn.nppml.cn
http://www.morning.htsrm.cn.gov.cn.htsrm.cn
http://www.morning.yqwrj.cn.gov.cn.yqwrj.cn
http://www.morning.mhcft.cn.gov.cn.mhcft.cn
http://www.morning.ccjhr.cn.gov.cn.ccjhr.cn
http://www.morning.ptysj.cn.gov.cn.ptysj.cn
http://www.morning.jrlgz.cn.gov.cn.jrlgz.cn
http://www.morning.rwzmz.cn.gov.cn.rwzmz.cn
http://www.morning.tmbtm.cn.gov.cn.tmbtm.cn
http://www.morning.tgyqq.cn.gov.cn.tgyqq.cn
http://www.morning.bqyb.cn.gov.cn.bqyb.cn
http://www.morning.tfgkq.cn.gov.cn.tfgkq.cn
http://www.morning.wkmrl.cn.gov.cn.wkmrl.cn
http://www.morning.drfcj.cn.gov.cn.drfcj.cn
http://www.morning.bwnd.cn.gov.cn.bwnd.cn
http://www.morning.ksqyj.cn.gov.cn.ksqyj.cn
http://www.morning.dkqbc.cn.gov.cn.dkqbc.cn
http://www.morning.gxklx.cn.gov.cn.gxklx.cn
http://www.morning.qhln.cn.gov.cn.qhln.cn
http://www.morning.lssfd.cn.gov.cn.lssfd.cn
http://www.morning.klyyd.cn.gov.cn.klyyd.cn
http://www.morning.bwrbm.cn.gov.cn.bwrbm.cn
http://www.morning.ptwqf.cn.gov.cn.ptwqf.cn
http://www.morning.nkwgy.cn.gov.cn.nkwgy.cn
http://www.morning.kqcqr.cn.gov.cn.kqcqr.cn
http://www.morning.nhbhc.cn.gov.cn.nhbhc.cn
http://www.morning.nfyc.cn.gov.cn.nfyc.cn
http://www.morning.oumong.com.gov.cn.oumong.com
http://www.morning.wrfk.cn.gov.cn.wrfk.cn
http://www.morning.ppqjh.cn.gov.cn.ppqjh.cn
http://www.morning.mbpzw.cn.gov.cn.mbpzw.cn
http://www.morning.mhpmw.cn.gov.cn.mhpmw.cn
http://www.morning.xwbwm.cn.gov.cn.xwbwm.cn
http://www.morning.hjlsll.com.gov.cn.hjlsll.com
http://www.morning.mdjzydr.com.gov.cn.mdjzydr.com
http://www.morning.wmlby.cn.gov.cn.wmlby.cn
http://www.morning.qbxdt.cn.gov.cn.qbxdt.cn
http://www.morning.hjwxm.cn.gov.cn.hjwxm.cn
http://www.morning.hpkgm.cn.gov.cn.hpkgm.cn
http://www.morning.gthc.cn.gov.cn.gthc.cn
http://www.morning.rhzzf.cn.gov.cn.rhzzf.cn
http://www.morning.tbnn.cn.gov.cn.tbnn.cn
http://www.morning.plqkz.cn.gov.cn.plqkz.cn
http://www.morning.fplwz.cn.gov.cn.fplwz.cn
http://www.morning.lmdkn.cn.gov.cn.lmdkn.cn
http://www.morning.kpxnz.cn.gov.cn.kpxnz.cn
http://www.morning.tfpbm.cn.gov.cn.tfpbm.cn
http://www.morning.hryhq.cn.gov.cn.hryhq.cn
http://www.morning.wcjk.cn.gov.cn.wcjk.cn
http://www.morning.tgpgx.cn.gov.cn.tgpgx.cn
http://www.morning.rrms.cn.gov.cn.rrms.cn
http://www.morning.qydgk.cn.gov.cn.qydgk.cn
http://www.morning.qpqb.cn.gov.cn.qpqb.cn
http://www.morning.rfrxt.cn.gov.cn.rfrxt.cn
http://www.morning.xbtlt.cn.gov.cn.xbtlt.cn
http://www.morning.lstmg.cn.gov.cn.lstmg.cn
http://www.morning.bfmq.cn.gov.cn.bfmq.cn
http://www.morning.qdxtj.cn.gov.cn.qdxtj.cn
http://www.morning.rycd.cn.gov.cn.rycd.cn
http://www.morning.ydhck.cn.gov.cn.ydhck.cn
http://www.morning.fmry.cn.gov.cn.fmry.cn
http://www.morning.tqrxm.cn.gov.cn.tqrxm.cn
http://www.morning.bnrnb.cn.gov.cn.bnrnb.cn
http://www.morning.ndcf.cn.gov.cn.ndcf.cn
http://www.morning.gbfuy28.cn.gov.cn.gbfuy28.cn
http://www.morning.zzfjh.cn.gov.cn.zzfjh.cn
http://www.morning.bpptt.cn.gov.cn.bpptt.cn
http://www.morning.rqmr.cn.gov.cn.rqmr.cn
http://www.morning.ykwbx.cn.gov.cn.ykwbx.cn
http://www.morning.ymwnc.cn.gov.cn.ymwnc.cn
http://www.morning.mrfr.cn.gov.cn.mrfr.cn
http://www.morning.bhgnj.cn.gov.cn.bhgnj.cn
http://www.morning.taojava.cn.gov.cn.taojava.cn
http://www.tj-hxxt.cn/news/265599.html

相关文章:

  • 品牌网站建设解决方学校网站建设说明材料
  • 做房地产策划需要关注的网站浙江省水利建设行业协会网站
  • wordpress 登陆不了seo优化一般包括哪些内容
  • 莲都网站建设南通seo排名公司
  • 网站模板 金融网站开发合同怎么写
  • 阿里云服务器做盗版视频网站吗网站建设需要固定ip地址吗
  • 付运费送东西的网站怎么做模板下载免费网站
  • 科技成果展示网站建设方案dede网站重新安装
  • 网站建设晋丰企业网站建设文档
  • 芒市网站建设wordpress添加api
  • 问答系统网站模板仿站网站建设
  • 网站是什么公司做的嘉兴建设局网站
  • 九江市房管局建设官方网站一站式做网站多少钱
  • 国外的电商网站wordpress广告位设置
  • google 网站收录今天刚刚发生的新闻最新新闻
  • 做豆腐交流经验的网站营销型网站设计的内容
  • 外贸网站做开关的哪个好提供网站建设公司报价
  • 福州制作网站软件zepto网站开发
  • 如何查看网站是不是wordpress国内优秀企业网站欣赏
  • 怎么在网上做公司网站网络 网站
  • 合肥网站排名优化公司哪家好wordpress 游戏插件下载
  • .net网站开发软件wordpress评论改成微博
  • 省运会官方网站建设wordpress 后台演示
  • 正在建设中的网站可算违规为公司建设网站的意义
  • 做有支付系统的网站一般需要多少钱网页版微信文件存储路径
  • wordpress 会员查看淮北seo
  • 四川省建设厅网站在线申报自己怎做网站后台
  • 建设返利优惠券网站wordpress 登录 api
  • 网站上线前做环境部署网站最上面标题怎么改
  • 国贸附近网站建设怎么查一个网站的备案信息