2024-01-05 11:11:15 +08:00
|
|
|
|
import Want from '@ohos.app.ability.Want'
|
|
|
|
|
|
import promptAction from '@ohos.promptAction'
|
2025-02-28 10:46:28 +08:00
|
|
|
|
import fileAccess from '@ohos.file.fileAccess'
|
2024-01-05 11:11:15 +08:00
|
|
|
|
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'
|
|
|
|
|
|
import common from '@ohos.app.ability.common'
|
|
|
|
|
|
import fs from '@ohos.file.fs'
|
2024-05-09 13:42:56 +08:00
|
|
|
|
|
2024-05-16 11:05:19 +08:00
|
|
|
|
const LOGTAG = 'LOGTAG'
|
2025-01-09 20:56:36 +08:00
|
|
|
|
|
2025-02-21 15:22:23 +08:00
|
|
|
|
export default class FileUtil {
|
|
|
|
|
|
public destFile: string
|
|
|
|
|
|
public filePathFdObj: Object = {}
|
2024-01-05 11:11:15 +08:00
|
|
|
|
/*
|
|
|
|
|
|
* @desc 创建并覆盖文件
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
2025-02-21 15:22:23 +08:00
|
|
|
|
public addFile = async (filePath: string, content: string, type?: string) => {
|
|
|
|
|
|
const { READ_WRITE,CREATE,APPEND } = fs.OpenMode
|
2024-07-09 11:11:31 +08:00
|
|
|
|
const isExit = fs.accessSync(filePath);
|
|
|
|
|
|
//文件存在先删除
|
2025-02-21 15:22:23 +08:00
|
|
|
|
if (isExit) {
|
2024-07-09 11:11:31 +08:00
|
|
|
|
fs.unlinkSync(filePath);
|
|
|
|
|
|
}
|
2024-01-05 11:11:15 +08:00
|
|
|
|
try {
|
2025-02-21 15:22:23 +08:00
|
|
|
|
let file = fs.openSync(filePath, READ_WRITE | CREATE);
|
2024-07-09 11:11:31 +08:00
|
|
|
|
//追加写入文件
|
2025-02-21 15:22:23 +08:00
|
|
|
|
fs.writeSync(file.fd, content)
|
2024-01-05 11:11:15 +08:00
|
|
|
|
fs.closeSync(file)
|
2025-02-21 15:22:23 +08:00
|
|
|
|
console.error(LOGTAG, '写入文件成功')
|
2025-01-09 20:56:36 +08:00
|
|
|
|
return true
|
2024-01-05 11:11:15 +08:00
|
|
|
|
|
2025-02-21 15:22:23 +08:00
|
|
|
|
} catch (e) {
|
2025-01-09 20:56:36 +08:00
|
|
|
|
promptAction.showToast({
|
2025-02-21 15:22:23 +08:00
|
|
|
|
message: `addFile文件失败` + filePath + JSON.stringify(e),
|
|
|
|
|
|
duration: 4000,
|
2025-01-09 20:56:36 +08:00
|
|
|
|
})
|
2025-02-21 15:22:23 +08:00
|
|
|
|
console.error(LOGTAG, '写入失败', JSON.stringify(e))
|
2024-01-05 11:11:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
|
|
|
* @desc 创建或者编辑文件
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
2025-02-21 15:22:23 +08:00
|
|
|
|
public editFile = async (filePath: string, content: string, fd?: number) => {
|
2025-01-09 20:56:36 +08:00
|
|
|
|
const {filePathFdObj} = this;
|
2025-02-21 15:22:23 +08:00
|
|
|
|
const { READ_WRITE,CREATE,APPEND } = fs.OpenMode
|
|
|
|
|
|
const newStr = content + '\n'
|
2025-01-09 20:56:36 +08:00
|
|
|
|
const thisFile = filePathFdObj[filePath];
|
2024-05-16 11:05:19 +08:00
|
|
|
|
try {
|
2025-02-21 15:22:23 +08:00
|
|
|
|
if (thisFile) {
|
|
|
|
|
|
fs.writeSync(thisFile.fd, newStr)
|
2025-01-09 20:56:36 +08:00
|
|
|
|
return fd;
|
2025-02-21 15:22:23 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
let file = fs.openSync(filePath, READ_WRITE | APPEND | CREATE);
|
|
|
|
|
|
fs.writeSync(file.fd, newStr)
|
2025-01-09 20:56:36 +08:00
|
|
|
|
this.filePathFdObj[filePath] = file
|
2024-12-24 17:27:02 +08:00
|
|
|
|
return file.fd
|
|
|
|
|
|
}
|
2024-12-29 21:43:12 +08:00
|
|
|
|
} catch (e) {
|
2025-01-09 20:56:36 +08:00
|
|
|
|
promptAction.showToast({
|
2025-02-21 15:22:23 +08:00
|
|
|
|
message: `editFile文件失败` + filePath + JSON.stringify(e),
|
|
|
|
|
|
duration: 4000,
|
2025-01-09 20:56:36 +08:00
|
|
|
|
})
|
2025-02-21 15:22:23 +08:00
|
|
|
|
console.error(LOGTAG, JSON.stringify(e))
|
2025-01-09 20:56:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
|
|
|
* @desc 关闭文件
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
2025-02-21 15:22:23 +08:00
|
|
|
|
public closeFile = async (filePath: string) => {
|
2025-01-09 20:56:36 +08:00
|
|
|
|
const {filePathFdObj} = this;
|
|
|
|
|
|
const thisFile = filePathFdObj[filePath];
|
2025-02-21 15:22:23 +08:00
|
|
|
|
if (thisFile) {
|
2025-01-09 20:56:36 +08:00
|
|
|
|
fs.closeSync(thisFile);
|
2025-02-21 15:22:23 +08:00
|
|
|
|
console.info(LOGTAG, filePath + '文件关闭成功')
|
2024-05-16 11:05:19 +08:00
|
|
|
|
}
|
2024-01-05 11:11:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
|
|
|
* @desc 读取文件
|
|
|
|
|
|
*
|
|
|
|
|
|
**/
|
2025-02-21 15:22:23 +08:00
|
|
|
|
public readFile = async (filePath: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
console.log('strrr', filePath)
|
2024-05-16 11:05:19 +08:00
|
|
|
|
const str = await fs.readText(filePath);
|
2024-01-05 11:11:15 +08:00
|
|
|
|
return str
|
2025-02-21 15:22:23 +08:00
|
|
|
|
} catch (e) {
|
2025-01-09 20:56:36 +08:00
|
|
|
|
promptAction.showToast({
|
2025-02-21 15:22:23 +08:00
|
|
|
|
message: `读取文件失败` + filePath + JSON.stringify(e),
|
|
|
|
|
|
duration: 4000,
|
2025-01-09 20:56:36 +08:00
|
|
|
|
})
|
2025-02-21 15:22:23 +08:00
|
|
|
|
console.log('readFile文件失败' + filePath + JSON.stringify(e))
|
2024-01-05 11:11:15 +08:00
|
|
|
|
return ''
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
|
|
|
* @desc获取系统目录里的文件列表
|
|
|
|
|
|
*/
|
2025-02-21 15:22:23 +08:00
|
|
|
|
public getDeviceList = async (folderPath?: string) => {
|
2024-01-05 11:11:15 +08:00
|
|
|
|
const {absolutePath,getFilePathList} = this;
|
2025-02-21 15:22:23 +08:00
|
|
|
|
return getFilePathList(`${absolutePath}/${folderPath}`, false)
|
2024-01-05 11:11:15 +08:00
|
|
|
|
};
|
2025-02-21 15:22:23 +08:00
|
|
|
|
private context: common.UIAbilityContext
|
|
|
|
|
|
private wantInfos: Want[]
|
2025-02-28 10:46:28 +08:00
|
|
|
|
private fileAccessHelper: fileAccess.FileAccessHelper
|
2025-02-21 15:22:23 +08:00
|
|
|
|
//后续文件路径待替换
|
|
|
|
|
|
private absolutePath = '/mnt/hmdfs/100/account/device_view/local/files/duolun'
|
|
|
|
|
|
private getFilePathList = async (filePath: string, isSdcard: boolean) => {
|
|
|
|
|
|
let fileName = [], sdCardFileName = [];
|
2024-01-05 11:11:15 +08:00
|
|
|
|
|
2025-02-21 15:22:23 +08:00
|
|
|
|
try {
|
|
|
|
|
|
const filenames = await fs.listFile(filePath);
|
|
|
|
|
|
for (let i = 0; i < filenames.length; i++) {
|
|
|
|
|
|
console.error(LOGTAG, `目录:${filePath}的子文件:${filenames[i]}`);
|
|
|
|
|
|
if (isSdcard) {
|
|
|
|
|
|
sdCardFileName.push(filenames[i])
|
|
|
|
|
|
} else {
|
|
|
|
|
|
fileName.push(filenames[i])
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return isSdcard ? sdCardFileName : fileName
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.error(LOGTAG, JSON.stringify(e));
|
2024-01-05 11:11:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
// 检索文件列表
|
|
|
|
|
|
public getSdCardPathList = async () => {
|
|
|
|
|
|
this.wantInfos = await fileAccess.getFileAccessAbilityInfo();
|
|
|
|
|
|
const {wantInfos,context} = this;
|
2025-02-21 15:22:23 +08:00
|
|
|
|
const fileAccessHelper = fileAccess.createFileAccessHelper(this.context, this.wantInfos);
|
2024-01-05 11:11:15 +08:00
|
|
|
|
this.fileAccessHelper = fileAccessHelper;
|
|
|
|
|
|
|
|
|
|
|
|
let isDone = false;
|
|
|
|
|
|
let rootIterator = null;
|
|
|
|
|
|
try {
|
|
|
|
|
|
rootIterator = await fileAccessHelper.getRoots();
|
|
|
|
|
|
|
|
|
|
|
|
while (!isDone) {
|
|
|
|
|
|
let isDones = false;
|
|
|
|
|
|
let rootInfo = rootIterator.next();
|
|
|
|
|
|
isDone = rootInfo.done; //返回true结束
|
|
|
|
|
|
console.error(LOGTAG, "根目录迭代器对象 next result = " + JSON.stringify(rootInfo));
|
|
|
|
|
|
if (!isDone) {
|
|
|
|
|
|
let deviceType = rootInfo.value.deviceType;
|
|
|
|
|
|
let displayName = rootInfo.value.displayName;
|
2025-02-21 15:22:23 +08:00
|
|
|
|
let uri: string = rootInfo.value.uri;
|
2024-01-05 11:11:15 +08:00
|
|
|
|
let deviceFlags = rootInfo.value.deviceFlags;
|
2025-02-21 15:22:23 +08:00
|
|
|
|
console.error(LOGTAG, `设备类型:${deviceType},设备名称:${displayName},设备根目录Uri:${uri},设备支持的能力:${deviceFlags}`);
|
2024-01-05 11:11:15 +08:00
|
|
|
|
|
2025-02-21 15:22:23 +08:00
|
|
|
|
if (uri.indexOf('/mnt/external/') > 0) {
|
2024-01-05 11:11:15 +08:00
|
|
|
|
// if('vol-8-1' ==displayName){
|
2025-02-21 15:22:23 +08:00
|
|
|
|
this.destFile = uri.split('ExternalFileManager')[1] + '/'
|
|
|
|
|
|
console.error(LOGTAG, `外置存储路径:` + this.destFile);
|
|
|
|
|
|
this.getFilePathList(this.destFile, true)
|
2024-01-05 11:11:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
2025-02-21 15:22:23 +08:00
|
|
|
|
console.error(LOGTAG, "getRoots failed, errCode:" + error.code + ", errMessage:" + error.message);
|
2024-01-05 11:11:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-02-21 15:22:23 +08:00
|
|
|
|
// 删除文件夹或者文件
|
|
|
|
|
|
/*
|
|
|
|
|
|
* @desc 删除文件夹或者文件
|
|
|
|
|
|
* @param{{type}} 1:文件夹 2:文件 3:自定义目录下文件
|
|
|
|
|
|
**/
|
2024-01-05 11:11:15 +08:00
|
|
|
|
// 文件系统初始化
|
|
|
|
|
|
private requestPermission = async () => {
|
|
|
|
|
|
const {context,absolutePath} = this;
|
|
|
|
|
|
let permissions: Array<Permissions> = [
|
|
|
|
|
|
'ohos.permission.READ_MEDIA',
|
|
|
|
|
|
'ohos.permission.WRITE_MEDIA'
|
|
|
|
|
|
];
|
|
|
|
|
|
this.wantInfos = await fileAccess.getFileAccessAbilityInfo();
|
|
|
|
|
|
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
|
2025-02-21 15:22:23 +08:00
|
|
|
|
atManager.requestPermissionsFromUser(context, permissions, async (code, result) => {
|
2024-01-05 11:11:15 +08:00
|
|
|
|
const permissionRequest = result.authResults[0]
|
2025-02-21 15:22:23 +08:00
|
|
|
|
if (permissionRequest == -1) {
|
2024-01-05 11:11:15 +08:00
|
|
|
|
promptAction.showToast({
|
|
|
|
|
|
message: "请先授权",
|
2025-02-21 15:22:23 +08:00
|
|
|
|
duration: 3000,
|
2024-01-05 11:11:15 +08:00
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2025-01-09 20:56:36 +08:00
|
|
|
|
|
2025-02-21 15:22:23 +08:00
|
|
|
|
constructor(wantInfos) {
|
|
|
|
|
|
const {requestPermission} = this;
|
|
|
|
|
|
this.wantInfos = wantInfos;
|
|
|
|
|
|
requestPermission();
|
|
|
|
|
|
fs.mkdir(this.absolutePath)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* @desc 校验文件夹,文件夹不存在会创建,支持嵌套
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
public initFolder = async (folderPath: string) => {
|
|
|
|
|
|
const {absolutePath} = this;
|
|
|
|
|
|
const folderList = folderPath.split('/').filter(folderName => folderName !== '');
|
|
|
|
|
|
|
|
|
|
|
|
let path = absolutePath
|
|
|
|
|
|
folderList.forEach((folderName => {
|
|
|
|
|
|
path += `/${folderName}`;
|
|
|
|
|
|
try {
|
|
|
|
|
|
const isExit = fs.accessSync(path);
|
|
|
|
|
|
if (!isExit) {
|
|
|
|
|
|
fs.mkdirSync(path)
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.info('初始化文件夹失败', path)
|
|
|
|
|
|
promptAction.showToast({
|
|
|
|
|
|
message: `初始化文件夹失败` + folderPath + JSON.stringify(e),
|
|
|
|
|
|
duration: 4000,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}));
|
|
|
|
|
|
return path;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public deleteF = async (path: string, type: 1 | 2 | 3) => {
|
|
|
|
|
|
const {getFilePathList,absolutePath} = this
|
|
|
|
|
|
if (type === 1) {
|
|
|
|
|
|
const fileList = await getFilePathList(`${absolutePath}/${path}`, false);
|
|
|
|
|
|
fileList.forEach(filePath => {
|
|
|
|
|
|
fs.unlinkSync(`${absolutePath}/${path}/${filePath}`);
|
|
|
|
|
|
})
|
|
|
|
|
|
fs.rmdirSync(`${absolutePath}/${path}`);
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (type === 2) {
|
|
|
|
|
|
fs.unlinkSync(`${absolutePath}/${path}`);
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
if (type === 3) {
|
|
|
|
|
|
fs.unlinkSync(`${path}`);
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取系统文件绝对路径
|
|
|
|
|
|
public getAbsolutePath = () => {
|
|
|
|
|
|
const {absolutePath} = this;
|
|
|
|
|
|
return absolutePath
|
|
|
|
|
|
}
|
2025-01-09 20:56:36 +08:00
|
|
|
|
|
2025-02-21 15:22:23 +08:00
|
|
|
|
public getFileContent = (filePath: string) => {
|
|
|
|
|
|
const {absolutePath} = this;
|
|
|
|
|
|
const { READ_WRITE } = fs.OpenMode
|
|
|
|
|
|
const path = `${absolutePath}/${filePath}`
|
|
|
|
|
|
const str = fs.readTextSync(path);
|
|
|
|
|
|
return str
|
|
|
|
|
|
}
|
2024-01-05 11:11:15 +08:00
|
|
|
|
}
|