• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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