1/* 2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import fileIo from '@ohos.fileio'; 17import fileAccess from '@ohos.file.fileAccess'; 18import Logger from '../utils/Logger'; 19import util from '@ohos.util'; 20import { BusinessError } from '@ohos.base'; 21import fs, { Filter } from '@ohos.file.fs'; 22 23const TAG = '[dlpmanager_MediaFileUri]'; 24const RECENT_MAX = 10; // 最近打开最大文件数 25const BUFFER_SIZE = 4096; // 文件读写缓冲区大小 26const COMMON_FD = -1; // 文件fd默认值 27 28class ListFileOption { 29 public recursion: boolean = false; 30 public listNum: number = 0; 31 public filter: Filter = {}; 32} 33 34export default class MediaFileUri { 35 content: string = ''; 36 private commonFd: number = COMMON_FD; 37 private fileNameList: Array<string> = []; 38 private fileUriList: Array<string> = []; 39 private fileAccessHelper: fileAccess.FileAccessHelper; 40 private fileInfos: Array<fileAccess.FileInfo> = []; 41 42 constructor() { 43 } 44 45 myWriteSync(fd: number, content: string, isClose: boolean): void { 46 try { 47 let result = fs.writeSync(fd, content); 48 Logger.info(TAG, 'myWriteSync: write result = ' + result); 49 } catch (err) { 50 Logger.error(TAG, 'myWriteSync: write failed with error:' + err); 51 } 52 if (isClose) { 53 this.closeSync(fd); 54 this.commonFd = COMMON_FD; 55 } else { 56 this.commonFd = fd; 57 } 58 } 59 60 // sync-close 61 closeSync(fd: number): void { 62 try { 63 fileIo.closeSync(fd); 64 Logger.info(TAG, 'closeSync file finish.'); 65 } catch (err) { 66 Logger.error(TAG, 'closeSync file error = ' + err); 67 } 68 } 69 70 readFileContent(uri: string, isRead: boolean = true, isClose: boolean = true): string { 71 let content = ''; 72 Logger.info(TAG, 'open path = ' + uri); 73 let file; 74 if (isClose || this.commonFd === COMMON_FD) { 75 try { 76 Logger.info(TAG, 'uri: ' + uri); 77 file = fs.openSync(uri, fs.OpenMode.READ_ONLY); 78 Logger.info(TAG, 'openReadSync: get fd success. file = ' + JSON.stringify(file)); 79 Logger.info(TAG, 'openReadSync: get fd success. fd = ' + file.fd); 80 this.commonFd = file.fd; 81 } catch (err) { 82 Logger.error(TAG, 'openReadSync: open file failed. error = ' + err); 83 return content; 84 } 85 if (file === undefined) { 86 Logger.error(TAG, 'openReadSync: open file failed. file = undefined.'); 87 return content; 88 } 89 } 90 if (isRead) { 91 try { 92 let buffer = new ArrayBuffer(BUFFER_SIZE); 93 let readOut = fs.readSync(this.commonFd, buffer, { 94 offset: 0 95 }); 96 content = bufferToString(buffer); 97 Logger.info(TAG, 'myReadSync: read result: ' + String.fromCharCode.apply(null, new Uint8Array(buffer.slice(0, readOut)))); 98 } catch (err) { 99 Logger.error(TAG, 'myReadSync: read error: ' + err); 100 return content; 101 } 102 103 if (isClose) { 104 this.closeSync(this.commonFd); 105 this.commonFd = COMMON_FD; 106 } else { 107 this.commonFd = this.commonFd; 108 } 109 } 110 return content; 111 } 112 113 writeFileContent(uri: string, content: string): void { 114 Logger.info(TAG, 'writeFileContent begin'); 115 let file = fs.openSync(uri, fs.OpenMode.READ_WRITE); 116 Logger.info(TAG, 'writeFileContent file fd: ' + file.fd); 117 let writeLen = fs.writeSync(file.fd, content); 118 Logger.info(TAG, 'writeFileContent write data to file succeed and size is:' + writeLen); 119 fs.closeSync(file); 120 } 121 122 async getFileData(url: string): Promise<void> { 123 let isDone: boolean = false; 124 let fileInfo = await this.fileAccessHelper.getFileInfoFromUri(url); 125 try { 126 let fileIterator = fileInfo.scanFile({ 127 suffix: ['.txt'] 128 }); 129 if (!fileIterator) { 130 Logger.info(TAG, 'listFile interface returns an undefined object'); 131 } 132 while (!isDone) { 133 let result = fileIterator.next(); 134 isDone = result.done; 135 if (!isDone) { 136 this.fileInfos.push(result.value); 137 } 138 } 139 } catch (err) { 140 Logger.info(TAG, `listFile failed, ${err}`); 141 } 142 } 143 144 async getAllFiles(context): Promise<void> { 145 Logger.info(TAG, 'getAllFiles begin'); 146 this.fileInfos = []; 147 this.fileAccessHelper = fileAccess.createFileAccessHelper(context); 148 let rootIterator = await this.fileAccessHelper.getRoots(); 149 let catalogueUrl: string = rootIterator.next().value.uri; 150 await this.getFileData(catalogueUrl); 151 for (let index = 0; index < this.fileInfos.length && index < RECENT_MAX; index++) { 152 this.fileNameList[index] = this.fileInfos[index].fileName; 153 this.fileUriList[index] = this.fileInfos[index].uri; 154 } 155 AppStorage.setOrCreate('fileNameList', this.fileNameList); 156 AppStorage.setOrCreate('fileUriList', this.fileUriList); 157 } 158 159 async getListFile(pathDir): Promise<void> { 160 let option = new ListFileOption(); 161 option.filter.suffix = ['.txt', '.doc', '.docx', '.dlp']; 162 fs.listFile(pathDir, option, (err: BusinessError, filenames: Array<string>) => { 163 if (err) { 164 Logger.info(TAG, 'list file failed with error message: ' + err.message + ', error code: ' + err.code); 165 } else { 166 Logger.info(TAG, 'listFile succeed'); 167 for (let i = 0; i < filenames.length; i++) { 168 Logger.info(TAG, 'filename: %s', filenames[i]); 169 } 170 } 171 }); 172 } 173} 174 175export function bufferToString(buffer: ArrayBuffer): string { 176 let textDecoder = new util.TextDecoder('utf-8', { 177 ignoreBOM: true 178 }); 179 let resultPut = textDecoder.decodeWithStream(new Uint8Array(buffer), { 180 stream: true 181 }); 182 return resultPut; 183}