1/* 2 * Copyright (c) 2023-2023 Huawei Device 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.file.fs'; 17import image from '@ohos.multimedia.image'; 18import type common from '@ohos.app.ability.common'; 19import { Log } from '@ohos/common'; 20import CheckEmptyUtils from '@ohos/common'; 21import FileModel from '../../Model/FileModel'; 22import { AppStorageKeyName, Constants } from '@ohos/common'; 23import { GlobalThisHelper, GlobalThisStorageKey} from '@ohos/common'; 24import FileAccess from '@ohos.file.fileAccess'; 25import AppStorageHelper from '../Adapter/AppStorageHelper'; 26import { StringUtil } from '@ohos/common'; 27 28 29const FILE_SEPARATOR = '/'; 30const TAG = 'FileUtil'; 31const READ_DATA_SIZE = 4096; 32 33export default class FileUtil { 34 /** 35 * Read Json file from disk by file path. 36 * 37 * @param {string} path - path of the target file. 38 * @return {any} - read object from file 39 */ 40 static readJsonFile(path: string): string { 41 Log.info(TAG, 'readJsonFile start execution'); 42 let readStreamSync = null; 43 let content: string = undefined; 44 try { 45 readStreamSync = Fileio.createStreamSync(path, 'r'); 46 content = this.getContent(readStreamSync); 47 Log.info(TAG, `readJsonFile finish execution content: ${content}`); 48 return <string> JSON.parse(content); 49 } catch (e) { 50 Log.error(TAG, `readJsonFile error: ${JSON.stringify(e)}`); 51 } finally { 52 if (readStreamSync !== undefined) { 53 readStreamSync.closeSync(); 54 } 55 } 56 return content; 57 } 58 59 /** 60 * Read String from disk by bundleName. 61 * 62 * @param {string} bundleName - bundleName as target file name 63 * @return {string} - read string from file 64 */ 65 static readStringFromFile(bundleName: string, abilityContext: common.Context): string { 66 Log.info(TAG, 'readStringFromFile start execution'); 67 const filePath = abilityContext.filesDir + FILE_SEPARATOR + bundleName + '.json'; 68 let readStreamSync = null; 69 let content: string = undefined; 70 try { 71 readStreamSync = Fileio.createStreamSync(filePath, 'r'); 72 content = this.getContent(readStreamSync); 73 Log.info(TAG, 'readStringFromFile finish execution'); 74 } catch (e) { 75 Log.error(TAG, `readStringFromFile error: ${JSON.stringify(e)}`); 76 } finally { 77 if (readStreamSync !== null) { 78 readStreamSync.closeSync(); 79 } 80 } 81 return content; 82 } 83 84 /** 85 * Write string to a file. 86 * 87 * @param {string} string - target string will be written to file 88 * @param {string} bundleName - bundleName as target file name 89 */ 90 static writeStringToFile(string: string, bundleName: string, abilityContext: common.Context): void { 91 Log.info(TAG, 'writeStringToFile start execution'); 92 const filePath = abilityContext.filesDir + FILE_SEPARATOR + bundleName + '.json'; 93 let writeStreamSync = null; 94 try { 95 writeStreamSync = Fileio.createStreamSync(filePath, 'w+'); 96 writeStreamSync.writeSync(string); 97 } catch (e) { 98 Log.error(TAG, `writeStringToFile error: ${JSON.stringify(e)}`); 99 } finally { 100 if (writeStreamSync !== null) { 101 writeStreamSync.closeSync(); 102 Log.info(TAG, 'writeStringToFile close sync'); 103 } 104 } 105 } 106 107 /** 108 * Read JSON object from a file. 109 * 110 * @param {object} readStreamSync - stream of target file 111 * @return {object} - object read from file stream 112 */ 113 static getContent(readStreamSync): string { 114 Log.info(TAG, 'getContent start'); 115 const bufArray = []; 116 let totalLength = 0; 117 let buf = new ArrayBuffer(READ_DATA_SIZE); 118 let len: number = readStreamSync.readSync(buf); 119 while (len !== 0) { 120 Log.debug(TAG, `getContent FileIO reading ${len}`); 121 totalLength += len; 122 if (len < READ_DATA_SIZE) { 123 buf = buf.slice(0, len); 124 bufArray.push(buf); 125 break; 126 } 127 bufArray.push(buf); 128 buf = new ArrayBuffer(READ_DATA_SIZE); 129 len = readStreamSync.readSync(buf); 130 } 131 Log.info(TAG, `getContent read finished: ${totalLength}`); 132 const contentBuf = new Uint8Array(totalLength); 133 let offset = 0; 134 for (const bufArr of bufArray) { 135 Log.debug(TAG, `getContent collecting: ${offset}`); 136 const uInt8Arr = new Uint8Array(bufArr); 137 contentBuf.set(uInt8Arr, offset); 138 offset += uInt8Arr.byteLength; 139 } 140 const content: string = String.fromCharCode.apply(null, new Uint8Array(contentBuf)); 141 return content; 142 } 143 144 /** 145 * 初始化ImageData, 将want传过来的uri解析 146 */ 147 public static async initImageData(fileList: Array<string>): Promise<Array<FileModel>> { 148 Log.info(TAG, 'initImageData'); 149 let errorCount: number = 0; 150 let errorFileName: string = 'file'; 151 let imageArray: FileModel[] = new Array<FileModel>(); 152 if (CheckEmptyUtils.isEmptyArr(fileList)) { 153 Log.error(TAG, 'fileList is empty'); 154 // @ts-ignore 155 return <object[]> imageArray; 156 } 157 for (let uri of fileList) { 158 let uriArr = uri.split(FILE_SEPARATOR); 159 let fileName = uriArr[uriArr.length-1]; 160 let file = undefined; 161 try { 162 file = Fileio.openSync(uri, Constants.READ_WRITE); 163 } catch (error) { 164 Log.error(TAG, 'open fail: ' + JSON.stringify(error)); 165 errorFileName = fileName; 166 errorCount++; 167 continue; 168 } 169 if (file === undefined || file.fd < 0) { 170 Log.error(TAG, 'open fail, file is undefined'); 171 errorFileName = fileName; 172 errorCount++; 173 continue; 174 } 175 Log.info(TAG, 'fd is ' + file.fd); 176 let imageSource = image.createImageSource(file.fd); 177 Log.info(TAG, 'image.createImageSource: ', JSON.stringify(imageSource)); 178 if (CheckEmptyUtils.isEmpty(imageSource)) { 179 Log.error(TAG, 'imageSource is error'); 180 errorFileName = fileName; 181 errorCount++; 182 continue; 183 } 184 let imageInfo = await Promise.resolve(this.getImageInfo(imageSource)); 185 Log.info(TAG, 'imageSource.getImageInfo: ', JSON.stringify(imageInfo)); 186 if (CheckEmptyUtils.isEmpty(imageInfo)) { 187 Log.error(TAG, 'imageInfo is error'); 188 errorFileName = fileName; 189 errorCount++; 190 continue; 191 } 192 imageArray.push(new FileModel(<number> file.fd, fileName, <string> uri, 193 <number> imageInfo.size.width, <number> imageInfo.size.height, imageSource)); 194 Log.debug(TAG, 'initImageData imageArray: ', JSON.stringify(imageArray)); 195 } 196 197 GlobalThisHelper.createValue<number>(errorCount, GlobalThisStorageKey.KEY_IMAGE_ERROR_COUNT, true); 198 GlobalThisHelper.createValue<string>(errorFileName, GlobalThisStorageKey.KEY_IMAGE_ERROR_NAME); 199 // @ts-ignore 200 return <object[]> imageArray; 201 } 202 203 /** 204 * 初始化ImageData, 将want传过来的fd解析 205 */ 206 public static async initFdImageData(fdList: Array<number>): Promise<Array<FileModel>> { 207 Log.info(TAG, 'initFdImageData'); 208 let imageArray: FileModel[] = new Array<FileModel>(); 209 if (CheckEmptyUtils.isEmptyArr(fdList)) { 210 Log.error(TAG, 'fdList is empty'); 211 // @ts-ignore 212 return <object[]> imageArray; 213 } 214 for (let fd of fdList) { 215 Log.info(TAG, 'fd is ' + fd); 216 let imageSource = image.createImageSource(fd); 217 if (CheckEmptyUtils.isEmpty(imageSource)) { 218 Log.error(TAG, 'imageSource is error'); 219 break; 220 } 221 let imageInfo = await imageSource.getImageInfo(); 222 if (CheckEmptyUtils.isEmpty(imageInfo)) { 223 Log.error(TAG, 'imageInfo is error'); 224 break; 225 } 226 imageArray.push(new FileModel(<number> fd, fd.toString(), fd.toString(), <number> imageInfo.size.width, <number> imageInfo.size.height, imageSource)); 227 } 228 // @ts-ignore 229 return <object[]> imageArray; 230 } 231 232 /** 233 * 转存图片 234 * 235 * @param pixelMap 236 * @param imagePath 237 * @param orientation 238 */ 239 static async saveImageToJpeg(pixelMap: image.PixelMap, imagePath: string, orientation: number): Promise<void> { 240 241 let imagePacker = image.createImagePacker(); 242 let rotation = orientation === Constants.NUMBER_1 ? Constants.NUMBER_90 : Constants.NUMBER_0; 243 Log.info(TAG, `rotation: ${rotation}`); 244 await pixelMap.rotate(rotation); 245 Log.info(TAG, 'rotation end'); 246 let arrayBuffer = await imagePacker.packing(pixelMap, { 247 format: 'image/jpeg', quality: 100 248 }); 249 Log.info(TAG, 'packing end'); 250 let file = Fileio.openSync(imagePath, Constants.READ_WRITE | Constants.CREATE); 251 if (file === undefined || file.fd < 0) { 252 Log.error(TAG, 'open fail'); 253 return; 254 } 255 Log.info(TAG, 'open end'); 256 let bytesWritten = await Fileio.write(file.fd, arrayBuffer); 257 if (bytesWritten) { 258 Log.debug('save success'); 259 Fileio.closeSync(file); 260 } 261 if (imagePacker !== undefined) { 262 imagePacker.release(); 263 } 264 } 265 266 static createJobsDir(filesDir: string): void { 267 let jobsDir = filesDir + Constants.FILE_SEPARATOR + Constants.TEMP_JOB_FOLDER; 268 try { 269 let result = Fileio.accessSync(jobsDir); 270 if (result) { 271 Log.info(TAG, 'jobs dir exist'); 272 } else { 273 Fileio.mkdirSync(jobsDir); 274 Log.info(TAG, 'jobs dir is not exist'); 275 } 276 } catch (err) { 277 Log.error(TAG, 'create dir error: ' + JSON.stringify(err)); 278 } 279 } 280 281 static deleteSource(jobFiles: string[]): void { 282 if (CheckEmptyUtils.isEmptyArr(jobFiles)) { 283 Log.error(TAG, 'jobFiles is empty'); 284 return; 285 } 286 let context = GlobalThisHelper.getValue(GlobalThisStorageKey.KEY_MAIN_ABILITY_CONTEXT); 287 if (CheckEmptyUtils.isEmpty(context)) { 288 Log.error(TAG, 'context is empty'); 289 return; 290 } 291 for (let jobFile of jobFiles) { 292 try { 293 let result = Fileio.accessSync(jobFile); 294 if (result) { 295 Fileio.unlinkSync(jobFile); 296 Log.info(TAG, 'delete success'); 297 } else { 298 Log.info(TAG, 'file is not exist'); 299 } 300 } catch (error) { 301 Log.info(TAG, 'delete error: ' + JSON.stringify(error)); 302 } 303 } 304 } 305 306 /** 307 * 获取所有待打印文件的fd 308 * 309 * @param jobFiles 待打印文件的uri list 310 */ 311 static getFdList(jobFiles: string[]): Array<number> { 312 try { 313 let fdList = new Array<number>(); 314 if (CheckEmptyUtils.isEmptyArr(jobFiles)) { 315 Log.error(TAG, 'jobFiles is empty'); 316 return fdList; 317 } 318 jobFiles.forEach((uri) => fdList.push(<number> Fileio.openSync(uri).fd)); 319 Log.info(TAG, 'fd list : ' + JSON.stringify(fdList)); 320 return fdList; 321 } catch (error) { 322 Log.error(TAG, 'getFdList error: ' + JSON.stringify(error)); 323 } 324 return new Array<number>(); 325 } 326 327 static getImageInfo(imageSource: image.ImageSource): Promise<image.ImageInfo> { 328 Log.info(TAG, 'getImageInfo: ', JSON.stringify(imageSource)); 329 return new Promise((returnResult) => { 330 imageSource.getImageInfo() 331 .then((info) => { 332 Log.info(TAG, 'getImageInfo info: ', JSON.stringify(info)); 333 returnResult(info); 334 }) 335 .catch((error) => { 336 Log.info(TAG, 'getImageInfo err: ', JSON.stringify(error)); 337 returnResult(undefined); 338 }); 339 }); 340 } 341} 342