鸿蒙开发实战:【文件管理】

介绍

本示例主要展示了文件管理相关的功能,使用[@ohos.multimedia.medialibrary]、[@ohos.filemanagement.userFileManager] 、[@ohos.fileio] 、[@ohos.file.fs]、[@ohos.app.ability.contextConstant]

等接口,实现了增添文件、删除文件、查找指定类型文件文件、复制并移动文件、切换加密分区和预览图片、监听文件的功能;

效果预览

首页图片列表图片预览文档删除加密分区
imageimageimageimageimage

使用说明

  1. 在主界面,可以点击图片、视频、文档、音频等按钮进入对应目录的文件列表浏览界面;

  2. 在文档列表浏览界面,点击“+”按钮,可以添加文件;

  3. 在文档列表浏览界面,长按列表项会出现删除图片,点击删除图标可以删除文件;

  4. 在图片文件列表界面,点击图片可以进入图片预览界面。

  5. 进入“我的手机”页面前应先安装[MyPhoneFilePage],在主页点击“我的手机”,进入应用目录下。

    1. 列表的上方是默认的EL2加密分区的应用根目录下文件列表,点击下方两个按钮“data/app/el3”和“data/app/el4”分别进入EL3和EL4加密分区应用根目录,进入后对文件或文件夹操作与EL2加密分区相同。
    2. 点击左下角“新建文件夹”按钮,在弹窗中输入文件夹名称,点击弹窗中的“确定”按钮,完成创建。
    3. 点击新建的文件夹,进入目录,在新目录中点击左下角的“新建文件”,在弹窗的窗口中填写文件名称,然后点击确定,完成创建。
    4. 点击右上角多选按钮,选择需要重命名的文件(仅选中一个文件时可用),点击重命名,在弹窗中修改文件名称,点击“确定”,完成修改。
    5. 点击右上角多选按钮,选择需要复制和移动的文件(可多选,并且不可移动到本身的子目录下),选中后点击左下角“复制和移动”按钮,在页面中点击目标目录会进入该目录,在目标目录下点击“移动到这”按钮,完成文件复制和移动。
    6. 点击右上角多选按钮,选择需要删除的文件,选中后点击右下角“更多”按钮,弹出的菜单中选择“删除”,在弹窗中点击“删除”,即可删除文件。
    7. 点击右上角多选按钮,选择一项需要修改时间的文件,选中后点击右下角“更多”按钮,弹出的菜单中选择“修改文件(夹)时间”,在弹窗的文本框中输入要修改的时间,点击“确定”,即可修改文件(夹)时间。
    8. 点击单个文件,可进入文件内容页面,点击右上角编辑按钮,进入编辑模式编辑、修改文件内容,然后点击右上角的保存按钮保存对文件的修改,点击左上角"X"按钮退出编辑模式,点击返回按钮返回上一页。
  6. 在主页点击“监听文件”,进入文件监听页面。

    1. 点击添加监听按钮,选择IN_CREATE监听,然后点击确定按钮,成功添加IN_CREATE监听。
    2. 点击添加按钮,成功添加一个文件,触发事件后日志显示为相应日志:event:256,fileName为新增文件的路径。
    3. 点击停止监听按钮,选择IN_CREATE监听,然后点击确定按钮,成功停止IN_CREATE监听。
    4. 点击添加按钮,成功添加一个文件,触发事件后日志无变化。
    5. 点击添加监听按钮,选择IN_DELETE监听,然后点击确定按钮,成功添加IN_DELETE监听。
    6. 选择要删除的文件item,左滑后点击删除图标,成功删除一个文件,触发事件后日志显示为相应日志:event:512,fileName为删除文件的路径。
    7. 点击停止监听按钮,选择IN_DELETE监听,然后点击确定按钮,成功停止IN_CREATE监听。
    8. 选择要删除的文件item,左滑后点击删除图标,成功删除一个文件,触发事件后日志无变化。
    9. 点击添加监听按钮,选择IN_MODIFY监听,然后点击确定按钮,成功添加IN_MODIFY监听。
    10. 选择要编辑的文件item,左滑后点击编辑图标,进入文件编辑界面,修改文件名和文件内容,修改之后点击保存图标,页面显示的文件文件大小发生变化,然后点击返回图标后返回文件监听界面,查看触发事件后日志显示为相应日志:event:2,fileName为修改后文件的路径。IN_MODIFY监听只监听文件内容是否发生变化,若单独修改文件名,则不会更新监听日志。
    11. 点击停止监听按钮,选择IN_MODIFY监听,然后点击确定按钮,成功停止IN_MODIFY监听。
    12. 选择要编辑的文件item,左滑后点击编辑图标,进入文件编辑界面,修改文件名和文件内容,修改之后点击保存图标,页面显示的文件文件大小发生变化,然后点击返回图标后返回文件监听界面,查看触发事件后日志无变化。

具体实现:

  • 增添文件、删除文件、查找指定类型文件文件和预览图片的功能接口封装在MediaLibraryManager,源码参考:[MediaLibraryManager.ts]
/*

 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import image from '@ohos.multimedia.image'

import mediaLibrary from '@ohos.multimedia.mediaLibrary'

import Logger from '../../utils/Logger'

import abilityAccessCtrl from '@ohos.abilityAccessCtrl';

import type { Permissions } from '@ohos.abilityAccessCtrl';



/**

 * 主要封装了mediaLibrary库相关的接口

 */

class MediaLibraryManager {

  requestPermission(context): void {

    let permissions: Array<Permissions> = [

      'ohos.permission.READ_MEDIA',

      'ohos.permission.WRITE_MEDIA'

    ]

    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();

    atManager.requestPermissionsFromUser(context, permissions, (code, result) => {

      Logger.debug('permissionRequest ' + JSON.stringify(code) + ' Result: ' + JSON.stringify(result))

    })

  }



  async getPixelMapByFileAsset(fileAsset: mediaLibrary.FileAsset): Promise<image.PixelMap> {

    if (fileAsset == undefined) {

      Logger.error('fileAsset undefined')

      // 异常情况下统一返回undefined,不建议使用null

      return undefined

    }

    Logger.debug('begin getPixelMapByFileAsset:' + fileAsset.displayName)

    let fd: number = undefined

    let pixelMap = undefined

    try {

      fd = await fileAsset.open('rw')

      Logger.debug('getPixelMapByFileAsset fd: ' + fd)

      let imageSource = image.createImageSource(fd)

      Logger.debug('imageSource: ' + JSON.stringify(imageSource))

      let decodingOptions = {

        sampleSize: 1,

        editable: true,

        desiredSize: { width: 3000, height: 4000 },

        rotate: 0,

        desiredPixelFormat: 3,

        desiredRegion: { size: { height: 6000, width: 8000 }, x: 0, y: 0 },

        index: 0

      }

      pixelMap = await imageSource.createPixelMap(decodingOptions)

      Logger.debug('pixel size: ' + pixelMap.getPixelBytesNumber())

      fileAsset.close(fd)

    } catch (err) {

      Logger.debug('err: ' + JSON.stringify(err))

    }

    return pixelMap

  }



  getMediaLibrary(context): mediaLibrary.MediaLibrary {

    return mediaLibrary.getMediaLibrary(context)

  }



  async getFileAssets(context, fileType: mediaLibrary.MediaType): Promise<mediaLibrary.FetchFileResult> {

    Logger.debug('begin getFileAssets, fileType:' + fileType)

    let fileKeyObj = mediaLibrary.FileKey

    let imagesFetchOption = {

      selections: fileKeyObj.MEDIA_TYPE + '= ?',

      selectionArgs: [fileType.toString()],

    }

    let fetchFileResult: mediaLibrary.FetchFileResult = undefined

    try {

      fetchFileResult = await this.getMediaLibrary(context).getFileAssets(imagesFetchOption)

      Logger.debug('fetchFileResult count:' + fetchFileResult.getCount())

    } catch (error) {

      Logger.error('fetchFileResult Error: ' + JSON.stringify(error))

    }

    return fetchFileResult

  }



  async getFileAssetsByName(context, name: string): Promise<mediaLibrary.FileAsset> {

    Logger.debug('begin getFileAssetsByName: ' + name)

    let fileKeyObj = mediaLibrary.FileKey

    let imagesFetchOption = {

      selections: fileKeyObj.DISPLAY_NAME + '= ?',

      selectionArgs: [name.toString()],

    }

    let fetchFileResult: mediaLibrary.FetchFileResult = undefined

    let file: mediaLibrary.FileAsset = undefined

    try {

      fetchFileResult = await this.getMediaLibrary(context).getFileAssets(imagesFetchOption)

      Logger.debug('fetchFileResult count:' + fetchFileResult.getCount())

      file = await fetchFileResult.getFirstObject()

    } catch (error) {

      Logger.error('fetchFileResult Error: ' + JSON.stringify(error))

    }

    return file

  }



  async getThumbnail(fileAsset: mediaLibrary.FileAsset): Promise<image.PixelMap> {

    let thumbnail = undefined

    try {

      thumbnail = await fileAsset.getThumbnail()

      Logger.debug('PixelMap size: ' + thumbnail.getPixelBytesNumber())

    } catch (error) {

      Logger.error('getThumbnail Error: ' + JSON.stringify(error))

    }

    return thumbnail

  }



  async createFileAsset(context, mediaType: mediaLibrary.MediaType,

                        dir: mediaLibrary.DirectoryType, fileName: string): Promise<mediaLibrary.FileAsset> {

    Logger.debug('createFileAsset: ' + fileName)

    let media = this.getMediaLibrary(context)

    let path = await media.getPublicDirectory(dir)

    return await media.createAsset(mediaType, fileName, path)

  }



  async deleteFileAsset(fileAsset: mediaLibrary.FileAsset): Promise<void> {

    Logger.debug('deleteFileAsset:' + fileAsset.displayName);

    await fileAsset.trash(true);

  }

}



export default new MediaLibraryManager()
  • 使用mediaLibrary.getMediaLibrary来获取MediaLibrary对象;

  • 读取每个文件的数据:使用MediaLibrary.getFileAssets读取满足条件的文件集合FetchFileResult,然后调用FetchFileResult.getFirstObject();

  • 创建模拟文件:使用MediaLibrary.getPublicDirectory()获取系统预定的目录,然后使用MediaLibrary.createAsset();

  • 删除指定路径的文件:使用MediaLibrary.deleteAsset();

  • 获取预览图:使用image.createImageSource()创建指定的文件资源ImageSource,然后调用ImageSource.createPixelMap(),接口参考:[@ohos.multimedia.image] 。

  • MyPhone模块中的文件增删、复制移动、查找功能封装在FileSystem,源码参考:[FileIoManager.ets]。

/*

 * Copyright (c) 2023 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import storageStatistics from '@ohos.file.storageStatistics';

import fileio from '@ohos.fileio';

import prompt from '@ohos.promptAction';

import { BusinessError } from '@ohos.base';

import Logger from '../../utils/Logger';

import { FileType, SubDirectoryType } from '../../mock/local/FileData';



// 大小和单位

const GB_MAGNITUDE: number = 1024 * 1024 * 1024;

const MB_MAGNITUDE: number = 1024 * 1024;

const KB_MAGNITUDE: number = 1024;

const GB_SYMBOL: string = 'GB';

const MB_SYMBOL: string = 'MB';

const KB_SYMBOL: string = 'KB';

const BYTE_SYMBOL: string = 'B';



const TAG: string = 'FileIoManager';



class FileSystem {

  // 获取文件大小

  getFileSize(filePath: string): string {

    try {

      let fileSize = fileio.statSync(filePath).size;

      if (fileSize / GB_MAGNITUDE > 1) {

        return `${(fileSize / GB_MAGNITUDE).toFixed(2)}${GB_SYMBOL}`;

      } else if (fileSize / MB_MAGNITUDE > 1) {

        return `${(fileSize / MB_MAGNITUDE).toFixed(2)}${MB_SYMBOL}`;

      } else if (fileSize / KB_MAGNITUDE > 1) {

        return `${(fileSize / KB_MAGNITUDE).toFixed(2)}${KB_SYMBOL}`;

      } else {

        return `${fileSize}${BYTE_SYMBOL}`;

      }

    } catch (err) {

      Logger.error(TAG, `getFileSize failed, code is ${err.code}, message is ${err.message}`);

      throw new Error(`getFileSize failed, code is ${err.code}, message is ${err.message}`);

    }

  }



/*

  // 总空间---默认GB

  async getTotalSize(): Promise<string> {

    let totalSize: number;

    try {

      totalSize = await storageStatistics.getTotalSize();

    } catch (err) {

      let error: BusinessError = err as BusinessError;

      Logger.error(TAG, `getTotalSize failed, code is ${error.code}, message is ${error.message}`);

      throw new Error(`getTotalSize failed, code is ${error.code}, message is ${error.message}`);

    }

    return `${(totalSize / GB_MAGNITUDE).toFixed(2)}${GB_SYMBOL}`;

  }



  // 剩余空间

  async getFreeSize(): Promise<string> {

    let freeSize: number;

    try {

      freeSize = await storageStatistics.getFreeSize();

    } catch (err) {

      let error: BusinessError = err as BusinessError;

      Logger.error(TAG, `getFreeSize failed, code is ${error.code}, message is ${error.message}`);

      throw new Error(`getFreeSize failed, code is ${error.code}, message is ${error.message}`);

    }



    if (freeSize / GB_MAGNITUDE > 1) {

      return `${(freeSize / GB_MAGNITUDE).toFixed(2)}${GB_SYMBOL}`;

    } else if (freeSize / MB_MAGNITUDE > 1) {

      return `${(freeSize / MB_MAGNITUDE).toFixed(2)}${MB_SYMBOL}`;

    } else if (freeSize / KB_MAGNITUDE > 1) {

      return `${(freeSize / KB_MAGNITUDE).toFixed(2)}${KB_SYMBOL}`;

    } else {

      return `${freeSize}${BYTE_SYMBOL}`;

    }

  }

*/



  // 根据沙箱路径打开目录

  getSubdirectory(filePath: string): Array<SubDirectoryType> {

    // 获取目录

    let dir: fileio.Dir;

    try {

      dir = fileio.opendirSync(filePath);

    } catch (err) {

      let error: BusinessError = err as BusinessError;

      Logger.error(TAG, `Open dir of path ${filePath} failed. error code is ${error.code}, message is ${error.message}`);

      throw new Error(`Open dir of path ${filePath} failed, code is ${error.code}, message is ${error.message}`);

    }

    // 读取的结果

    let dirent: fileio.Dirent;

    // 结果数组

    class SubDirectory {

      name: string = '';

      type: number = 0;

      time: Date;

      childrenNum: number = 0;

      fileSize: string = '';

      constructor(time: Date) {

        this.time = time;

      }

    }

    let subdirectory: Array<SubDirectory> = []

    do {

      dirent = dir.readSync();

      if (dirent) {

        let subdirectoryNum: number = 0;

        let fileSize: string = '';

        let time: Date = new Date();

        // 如果是文件夹,就读取文件夹中文件的数量

        if (dirent.isDirectory()) {

          subdirectoryNum = this.getSubdirectoryNum(filePath + `${dirent.name}`);

          time = this.getFileTime(filePath + `${dirent.name}`);

        } else {

          // 如果不是文件夹,就读取文件大小和时间

          fileSize = this.getFileSize(filePath + `${dirent.name}`);

          time = this.getFileTime(filePath + `${dirent.name}`);

        }

        let item = new SubDirectory(time);

        item.name = dirent.name;

        item.type = dirent.isDirectory() ? 1 : 2;

        item.childrenNum = subdirectoryNum;

        item.fileSize = fileSize;

        subdirectory.push(item);

      }

    } while (dirent);

    return subdirectory;

  }



  // 获取目录中的子目录个数

  getSubdirectoryNum(filePath: string): number {

    let dir: fileio.Dir;

    try {

      dir = fileio.opendirSync(filePath);

    } catch (err) {

      let error: BusinessError = err as BusinessError;

      Logger.error(TAG, `Open dir of path ${filePath} failed. error code is ${error.code}, message is ${error.message}`);

      throw new Error(`Open dir of path ${filePath} failed, code is ${error.code}, message is ${error.message}`);

    }

    // 读取的结果

    let dirent: fileio.Dirent;

    // 记录子目录的个数

    let subdirectoryNum = 0;

    do {

      dirent = dir.readSync();

      if (dirent) {

        subdirectoryNum++;

      }

    } while (dirent);

    return subdirectoryNum;

  }



  // 获取文件修改时间

  getFileTime(filePath: string): Date {

    try {

      let fileTime = fileio.statSync(filePath).mtime;

      return new Date(fileTime * 1000);

    } catch (err) {

      Logger.error(TAG, `getFileTime failed, code is ${err.code}, message is ${err.message}`);

      throw new Error(`getFileTime failed, code is ${err.code}, message is ${err.message}`);

    }

  }



  // 创建目录

  createDirectory(filePath: string): void {

    try {

      fileio.mkdirSync(filePath);

    } catch (err) {

      Logger.error(TAG, `create directory failed, code is ${err.code}, message is ${err.message}`);

    }

  }



  // 创建文件

  createFile(filePath: string): void {

    try {

      fileio.openSync(filePath, 0o100, 0o666);

    } catch (err) {

      Logger.error(TAG, `create file failed, code is ${err.code}, message is ${err.message}`);

    }

  }



  // 删除目录和文件---选中项

  deleteSelected(dataArray: Map<string, number>): void {

    try {

      dataArray.forEach((value, data) => {

        if (value === 1) {

          fileio.rmdirSync(data);

        } else {

          fileio.unlinkSync(data);

        }})

      prompt.showToast({ message: $r('app.string.label_delete_success') });

    } catch (err) {

      Logger.error(TAG, `delete failed, code is ${err.code}, message is ${err.message}`);

    }

  }



  // 复制文件

  copyFile(filePath: string, newFilePath: string): void {

    try {

      // 遍历数据直接copy所有项目

      fileio.copyFileSync(filePath, newFilePath);

    } catch (err) {

      Logger.error(TAG, `copy file failed, code is ${err.code}, message is ${err.message}`);

    }

  }



  // 重命名文件

  renameFile(filePath: string, newFilePath: string): void {

    try {

      fileio.renameSync(filePath, newFilePath);

    } catch (err) {

      Logger.error(TAG, `rename file failed, code is ${err.code}, message is ${err.message}`);

    }

  }



  // 开始移动文件

  startMoveFile(needMoveFiles: Array<FileType>, newFilePath: string): void {

    // 遍历数据

    needMoveFiles.forEach((file: FileType): void => {

      // 如果是目录

      if (file.type === 1) {

        // 先创建这个目录

        this.createDirectory(`${newFilePath}/${file.fileName}`);

        // 获取当前文件夹下的所有文件目录

        let subdirectory = this.getSubdirectory(`${file.filePath}/`);

        // 处理为我们想要的格式

        let needMoveFiles: Array<FileType> = [];

        // 遍历子目录数据

        subdirectory.forEach((subdirectoryData: SubDirectoryType) => {

          let data: FileType = {

            filePath: `${file.filePath}/${subdirectoryData.name}`,

            fileName: subdirectoryData.name,

            type: subdirectoryData.type

          };

          // 逐一添加进去

          needMoveFiles.push(data);

        })

        // 使用我们的数据递归

        this.startMoveFile(needMoveFiles, `${newFilePath}/${file.fileName}`);

      } else {

        this.copyFile(file.filePath, `${newFilePath}/${file.fileName}`);

      }

    })

  }

}



export default new FileSystem();
  • 读取文件列表:使用fileio.opendirSync()打开指定目录dir,然后使用dir.readSync()读取文件内容dirent,在调用dirent中相关api获取想要的文件参数;

  • 创建目录:使用fileio.mkdirSync()创建文件夹;

  • 创建文件:使用fileio.openSync()创建文件;

  • 删除选中内容:使用fileio.rmdirSync()删除文件夹,使用fileio.unlinkSync()删除文件;

  • 复制文件:使用fileio.copyFileSync()复制目标文件;

  • 移动文件:使用fileio.mkdirSync()创建指定目录,再递归选中目录中的文件,将内部的文件创建到指定的位置。

  • 修改加密分区:修改应用上下文Context的area,实现当前加密分区的修改。

  • 在Library模块中通过封装FileManager向外提供功能接口,如MediaLibraryManager.getPixelMapByFileAsset(),源码参考:[FileManager.ts]

/*

 * Copyright (c) 2022 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



import mediaLibrary from '@ohos.multimedia.mediaLibrary'

import image from '@ohos.multimedia.image'

import MediaLibraryManager from './medialibrary/MediaLibraryManager'

import LocalMockData from '../mock/local/LocalMockData'



/**

 * 文件管理接口,统一封装了各模块对外提供的功能接口

 */

class FileManager {

  /**

   * 申请文件管理权限

   * @param context 上下文对象

   */

  requestPermission(context): void {

    MediaLibraryManager.requestPermission(context)

  }



  /**

   * 通过传入文件对象FileAsset,获取到文件中的图片PixelMap对象

   * @param fileAsset 文件对象

   * @return Promise<image.PixelMap> 返回PixelMap对象

   */

  async getPixelMapByFileAsset(fileAsset: mediaLibrary.FileAsset): Promise<image.PixelMap> {

    return await MediaLibraryManager.getPixelMapByFileAsset(fileAsset)

  }



  /**

   * 通过传入文件类型,获取到不同的文件列表信息

   * @param context 上下文对象

   * @param fileType 文件类型

   * @return Promise<mediaLibrary.FetchFileResult> 返回文件列表信息

   */

  async getFileAssets(context, fileType: mediaLibrary.MediaType): Promise<mediaLibrary.FetchFileResult> {

    return await MediaLibraryManager.getFileAssets(context, fileType)

  }



  /**

   * 通过文件名称获取文件对象

   * @param context 上下文对象

   * @param name 文件名称

   * @return Promise<mediaLibrary.FileAsset> 返回文件对象信息

   */

  async getFileAssetsByName(context, name: string): Promise<mediaLibrary.FileAsset> {

    return await MediaLibraryManager.getFileAssetsByName(context, name)

  }



  /**

   * 获取文件缩略图

   * @param fileAsset 文件对象

   * @return Promise<image.PixelMap> 返回缩略图信息

   */

  async getThumbnail(fileAsset: mediaLibrary.FileAsset): Promise<image.PixelMap> {

    return await MediaLibraryManager.getThumbnail(fileAsset)

  }



  /**

   * 创建文件

   * @param context 上下文对象

   * @param mediaType 文件类型

   * @param dir 文件路径

   * @param fileName 文件名称

   * @return Promise<mediaLibrary.FileAsset> 返回匹配的文件信息

   */

  async createFileAsset(context, mediaType: mediaLibrary.MediaType,

                        dir: mediaLibrary.DirectoryType, fileName: string): Promise<mediaLibrary.FileAsset> {

    return await MediaLibraryManager.createFileAsset(context, mediaType, dir, fileName)

  }



  /**

   * 删除文件

   * @param fileAsset 文件对象

   */

  async deleteFileAsset(fileAsset: mediaLibrary.FileAsset): Promise<void> {

    await MediaLibraryManager.deleteFileAsset(fileAsset);

  }



  /**

   * 创建模拟文件

   * @param context 上下文对象

   * @param mediaType 文件类型

   * @return Promise<mediaLibrary.FileAsset> 返回文件对象

   */

  async createTxtFileAsset(context): Promise<mediaLibrary.FileAsset> {

    return await LocalMockData.createFileAsset(context)

  }



  /**

   * 该文件是否支持预览

   * @param fileName 文件名

   * @return boolean ture表示支持,false表示不支持

   */

  isSupportPreview(fileName: string): boolean {

    return LocalMockData.isSupportPreview(fileName)

  }

}



export default new FileManager()
  • 如效果预览中的图片列表,读取指定类型的文件:在[FileList.ets]中调用FileManager.getFileAssets();

  • 创建模拟文件:在[FileList.ets] 中调用FileManager.createTxtFileAsset();

  • 删除指定路径的文件:在[FileList.ets] 中调用FileManager.deleteFileAsset();

  • 获取缩略图:在[ThumbnailImage.ets] 中调用FileManager.getThumbnail();

  • 如效果预览中的图片预览,获取预览图:在[ImagePreview.ets] 中调用FileManager.getPixelMapByFileAsset()。

  • 监听文件模块中的文件增删、查找、修改、监听功能封装在MyWatcher。

  • 增加文件、删除文件、监听文件、停止监听文件:在[WatcherFile.ets] 中调用MyWathcer.addFileToWatcher()、MyWathcer.deleteFileToWatcher()、MyWathcer.startWatcher(watcherName)、MyWathcer.stopWatcher();

  • 修改文件:在[EditFile.ets]

中调用MyWatcher.modifyFileToWatcher()。

鸿蒙Next技术知识已更新gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md请前往参考。

QQ浏览器截图20240311144813.png

约束与限制

  1. 本示例仅支持标准系统上运行,支持设备:RK3568;
  2. 本示例为Stage模型,仅支持API11版本SDK,SDK版本号(API Version 11 Beta),镜像版本号(4.1Beta)。
  3. 本示例需要使用DevEco Studio 版本号(4.0Release)及以上版本才可编译运行。
  4. 本示例涉及调用系统权限的接口,需要配置允许权限列表,在配置文件中的“allowed-acls”字段中增加"ohos.permission.READ_MEDIA", “ohos.permission.WRITE_MEDIA”, “ohos.permission.FILE_ACCESS_MANAGER”, "ohos.permission.STORAGE_MANAGER"四个权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/472648.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java基础夯实——八股文【2024面试题案例代码】

1、Java当中的基本数据类型 Java中常见的数据类型及其对应的字节长度和取值范围如下&#xff1a; byte&#xff1a;1字节&#xff0c;取值范围为-128到127。short&#xff1a;2字节&#xff0c;取值范围为-32,768到32,767。int&#xff1a;4字节&#xff0c;取值范围为-2,147…

【Linux】初识进程

目录 操作系统是什么 设计操作系统的目的 操作系统的定位 如何理解管理 管理的本质 管理的例子 计算机的管理概念图 操作系统管理逻辑的六字真言 系统调用和库函数的概念 进程 进程的概念 什么是PCB&#xff1f; PCB的主要内容 如何查看进程&#xff1f; 通过系统…

数据结构与算法----复习Part 17 (图(Graph)初步)

本系列是算法通关手册LeeCode的学习笔记 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 目录 一&#xff0c;图&#xff08;Graph&#xff09; 图的分类 顶点的度 环形图和无环图 连通图和非连通图 强连…

远程服务器安装portainer —— docker的可视化工具

可视化工具&#xff08;了解即可&#xff09; 最常用的工具是 portainer portainer 是一个开源的容器管理平台&#xff0c;它提供了一个简单易用的用户界面&#xff0c;用于管理和监控 docker 容器集群。通过 portainer&#xff0c;用户可以轻松地进行容器的部署、启动、停止…

C++_回文串

目录 回文子串 最长回文子串 分割回文串 IV 分割回文串 II 最长回文子序列 让字符串成为回文串的最少插入次数 回文子串 647. 回文子串 思路&#xff0c;i j表示改范围内是否为回文串&#xff0c; ②倒着遍历是为了取出dp[i 1][j - 1] ③i j 只有一对&#xff0c;不会重复…

算法沉淀——贪心算法五(leetcode真题剖析)

算法沉淀——贪心算法五 01.跳跃游戏 II02.跳跃游戏03.加油站04.单调递增的数字 01.跳跃游戏 II 题目链接&#xff1a;https://leetcode.cn/problems/jump-game-ii/ 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转…

一共有哪 3 类线程安全问题

一共有哪 3 类线程安全问题 运行结果错误发布和初始化导致线程安全问题活跃性问题死锁活锁饥饿 要想弄清楚有哪 3 类线程安全问题&#xff0c;首先需要了解什么是线程安全&#xff0c;线程安全经常在工作中被提到&#xff0c;比如&#xff1a;你的对象不是线程安全的&#xff0…

2024新版计算器:腾讯云服务器价格计算器,报价不求人

腾讯云服务器价格计算器可以一键计算出云服务器的精准报价&#xff0c;包括CVM实例规格价格、CPU内存费用、公网带宽收费、存储系统盘和数据盘详细费用&#xff0c;腾讯云百科txybk.com分享腾讯云价格计算器链接入口、使用方法说明&#xff0c;在腾讯云百科 txy.wiki 查看当前最…

全球盲盒火热下,海外盲盒APP助力我国盲盒出海

盲盒具有不确定性&#xff0c;与各类热门影视动漫合作推出的专属盲盒商品&#xff0c;吸引了无数年轻人&#xff0c;成为了年轻人的娱乐消费首选方式。 在互联网电商的推动下&#xff0c;盲盒在全球内的市场规模迅速扩大。受到市场增长的影响&#xff0c;各类资本公司也纷纷进…

【Python】import无法导入某一目录下的文件

问题&#xff1a; 如图所示&#xff0c;我在mains文件夹下面有一个main_VAE.py的程序&#xff0c;在与mains同级目录的models文件夹下面有一个variational_autoencoder.py&#xff08;可能上图无法显示完全models文件夹&#xff09;&#xff0c;此时我想要在main_VAE.py程序中导…

数据结构从入门到精通——直接选择排序

直接选择排序 前言一、选择排序的基本思想&#xff1a;二、直接选择排序三、直接选择排序的特性总结&#xff1a;四、直接选择排序的动画展示五、直接选择排序的代码展示test.c 六、直接选择排序的优化test.c 前言 直接选择排序是一种简单的排序算法。它的工作原理是每一次从未…

Linux-docker安装数据库mysql

1、拉去mysql镜像&#xff1a; docker pull mysql2、创建容器挂载路径 mkdir -p /usr/local/jiuxiang/mysql/data # 数据存储位置 mkdir -p /usr/local/jiuxiang/mysql/logs # 日志存储位置 mkdir -p /usr/local/jiuxiang/mysql/conf # 配置文件3、启动容器 docker run -…

详细分析Python模块中的雪花算法(附模板)

目录 前言1. 基本知识2. 模板3. Demo 前言 分布式ID的生成推荐阅读&#xff1a;分布式ID生成方法的超详细分析&#xff08;全&#xff09; 1. 基本知识 Snowflake 算法是一种用于生成全局唯一 ID 的分布式算法&#xff0c;最初由 Twitter 设计并开源 它被设计用于解决分布式…

sentinel整合openFeign实现fall服务降级

服务提供方: 导入依赖&#xff1a; <!--openfeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--alibaba-sentinel--><depend…

猫猫编号

解法&#xff1a; 暴力 #include<iostream> #include<algorithm> #include<vector> using namespace std; #define endl \nint main() {int n, m, sum 1;cin >> n >> m;string s;cin >> s;int pre s[0] - 0;int t 0;for (int i 1; i…

【DAY13 软考中级备考笔记】操作系统

操作系统 3月17日 – 天气&#xff1a;晴 凑着周末&#xff0c;赶紧把操作系统完结一下。 1. 管程 管程也属于操作系统中的一种同步机制&#xff0c;为了解决多线程环境中的并发控制问题。它提供了一系列的高级同步原语。 作用于信号量一样&#xff0c;但是管程便携程序更加简单…

腾讯云优惠券介绍、领取入口及使用教程

腾讯云作为国内领先的云服务提供商&#xff0c;一直以其稳定、高效、安全的服务赢得了广大用户的信赖。为了回馈广大用户&#xff0c;腾讯云经常会推出各种优惠活动&#xff0c;其中优惠券就是最为常见和受欢迎的一种。 一、腾讯云优惠券介绍 腾讯云优惠券是腾讯云官方推出的一…

Json Web Token(JWT) 快速入门

推荐视频&#xff1a;【从零开始掌握JWT】 目录 第一章 会话跟踪 01 使用Cookie和Session&#xff0c;jsessionid 02 使用token 例子一&#xff1a;自定义token 例子二&#xff1a;使用redis存储token 第二章 会用JWT 01 TOKEN的特点 02 什么时候使用JWT 03 JWS-JWE…

Linux学习:git补充与调试工具gdb

目录 1. git版本控制器&#xff08;续&#xff09;1.1 git本地仓库结构1.2 git实现版本控制与多人协作的方式1.3 git相关指令&#xff0c;多分支模型与.gitignore文件 2. gdb调试工具2.1 企业项目开发流程简述与调试的必要性2.2 bug的调试思路方法与调式工具的使用 1. git版本控…

目标检测---IOU计算详细解读(IoU、GIoU、DIoU、CIoU、EIOU、Focal-EIOU、SIOU、WIOU)

常见IoU解读与代码实现 一、✒️IoU&#xff08;Intersection over Union&#xff09;1.1 &#x1f525;IoU原理☀️ 优点⚡️缺点 1.2 &#x1f525;IoU计算1.3 &#x1f4cc;IoU代码实现 二、✒️GIoU&#xff08;Generalized IoU&#xff09;2.1 GIoU原理☀️优点⚡️缺点 2…