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