1/**
2 * Copyright (c) 2021-2022 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
16/**
17 * An util that provides io functionality between file and JSON object.
18 */
19
20import fs from '@ohos.file.fs';
21import util from '@ohos.util';
22import { Log } from './Log';
23
24const TAG = 'FileUtils';
25
26const READ_DATA_SIZE = 4096;
27
28export default class FileUtils {
29
30  /**
31   * Read Json file from disk by file path.
32   *
33   * @param {string} filePath - filePath as the absolute path to the target file.
34   * @return {any} - read object from file
35   */
36  static readJsonFile(filePath: string): any {
37    Log.showDebug(TAG, 'readJsonFile start execution');
38    let readStreamSync = null;
39    try {
40      readStreamSync = fs.createStreamSync(filePath, 'r');
41      const content = this.getContent(readStreamSync);
42      return JSON.parse(content);
43    } catch (e) {
44      Log.showError(TAG, `readJsonFile error: ${JSON.stringify(e)}`);
45    } finally {
46      readStreamSync.closeSync();
47    }
48  }
49
50  /**
51   * Read String from disk by bundleName.
52   *
53   * @param {string} filePath - filePath as the absolute path to the target file.
54   * @return {string} - read string from file
55   */
56  static readStringFromFile(filePath: string): string {
57    Log.showDebug(TAG, 'readStringFromFile start execution');
58    let readStreamSync = null;
59    try {
60      readStreamSync = fs.createStreamSync(filePath, 'r');
61      const content = this.getContent(readStreamSync);
62      return content;
63    } catch (e) {
64      Log.showError(TAG, `readStringFromFile error: ${JSON.stringify(e)}, filePath: ${filePath}`);
65    } finally {
66      if (readStreamSync) {
67        readStreamSync.closeSync();
68      }
69    }
70  }
71
72  /**
73   * Write string to a file.
74   *
75   * @param {string} str - target string will be written to file.
76   * @param {string} filePath - filePath as the absolute path to the target file.
77   */
78  static writeStringToFile(str: string, filePath: string): void {
79    Log.showDebug(TAG, 'writeStringToFile start execution');
80    let writeStreamSync = null;
81    try {
82      writeStreamSync = fs.createStreamSync(filePath, 'w+');
83      let number = writeStreamSync.writeSync(str);
84      Log.showDebug(TAG, 'writeStringToFile number: ' + number);
85    } catch (e) {
86      Log.showError(TAG, `writeStringToFile error: ${JSON.stringify(e)}`);
87    } finally {
88      writeStreamSync.closeSync();
89      Log.showDebug(TAG, 'writeStringToFile close sync');
90    }
91  }
92
93  /**
94   * Read JSON object from a file.
95   *
96   * @param {object} readStreamSync - stream of target file
97   * @return {object} - object read from file stream
98   */
99  static getContent(readStreamSync: any): string {
100    Log.showDebug(TAG, 'getContent start');
101    const bufArray = [];
102    let totalLength = 0;
103    let buf = new ArrayBuffer(READ_DATA_SIZE);
104    let len = readStreamSync.readSync(buf);
105    while (len != 0) {
106      Log.showDebug(TAG, `getContent FileIO reading ${len}`);
107      totalLength += len;
108      if (len < READ_DATA_SIZE) {
109        buf = buf.slice(0, len);
110        bufArray.push(buf);
111        break;
112      }
113      bufArray.push(buf);
114      buf = new ArrayBuffer(READ_DATA_SIZE);
115      len = readStreamSync.readSync(buf);
116    }
117    Log.showDebug(TAG, `getContent read finished: ${totalLength}`);
118    const contentBuf = new Uint8Array(totalLength);
119    let offset = 0;
120    for (const bufArr of bufArray) {
121      Log.showDebug(TAG, `getContent collecting: ${offset}`);
122      const uInt8Arr = new Uint8Array(bufArr);
123      contentBuf.set(uInt8Arr, offset);
124      offset += uInt8Arr.byteLength;
125    }
126    let textDecoder = util.TextDecoder.create('utf-8', {ignoreBOM: true});
127    const content = textDecoder.decodeWithStream(contentBuf, {stream: false});
128    return content;
129  }
130
131  /**
132   * Check if the file exists.
133   *
134   * @param {string} filePath - filePath as the absolute path to the target file.
135   * @return {boolean} - boolean true(Exist)
136   */
137  static isExist(filePath: string): boolean {
138    let result: boolean = false;
139    try {
140      result = fs.accessSync(filePath);
141      Log.showDebug(TAG, 'accessSync success.');
142    } catch(e) {
143      Log.showError(TAG, `isExit error: ${JSON.stringify(e)}`);
144      result = false;
145    }
146    return result;
147  }
148
149  /**
150   * Delete Files.
151   *
152   * @param {string} filePath - filePath as the absolute path to the target file.
153   */
154  static deleteConfigFile(filePath: string): void {
155    try {
156      fs.unlinkSync(filePath);
157    } catch(e) {
158      Log.showError(TAG, `deleteFile error: ${JSON.stringify(e)}`);
159    }
160  }
161}