16e80583aSopenharmony_ci/**
26e80583aSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
36e80583aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
46e80583aSopenharmony_ci * you may not use this file except in compliance with the License.
56e80583aSopenharmony_ci * You may obtain a copy of the License at
66e80583aSopenharmony_ci *
76e80583aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
86e80583aSopenharmony_ci *
96e80583aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
106e80583aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
116e80583aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126e80583aSopenharmony_ci * See the License for the specific language governing permissions and
136e80583aSopenharmony_ci * limitations under the License.
146e80583aSopenharmony_ci */
156e80583aSopenharmony_ci
166e80583aSopenharmony_ciimport featureAbility from '@ohos.ability.featureAbility';
176e80583aSopenharmony_ciimport fileIo from '@ohos.fileio';
186e80583aSopenharmony_ciimport { Log } from '../utils/Log';
196e80583aSopenharmony_ci
206e80583aSopenharmony_ciconst TAG = 'FileManager';
216e80583aSopenharmony_ciconst READ_DATA_SIZE = 4096;
226e80583aSopenharmony_ci
236e80583aSopenharmony_ci/**
246e80583aSopenharmony_ci * Wrapper class for fileIo interfaces.
256e80583aSopenharmony_ci */
266e80583aSopenharmony_ciexport default class FileManager {
276e80583aSopenharmony_ci  private baseDir: string | undefined;
286e80583aSopenharmony_ci
296e80583aSopenharmony_ci  static getInstance(): FileManager {
306e80583aSopenharmony_ci    if (globalThis.FileManagerInstance == null) {
316e80583aSopenharmony_ci      globalThis.FileManagerInstance = new FileManager();
326e80583aSopenharmony_ci    }
336e80583aSopenharmony_ci    return globalThis.FileManagerInstance;
346e80583aSopenharmony_ci  }
356e80583aSopenharmony_ci
366e80583aSopenharmony_ci  private async getBaseDir(): Promise<void> {
376e80583aSopenharmony_ci    const context = featureAbility.getContext();
386e80583aSopenharmony_ci    await context.getFilesDir()
396e80583aSopenharmony_ci      .then((data) => {
406e80583aSopenharmony_ci        Log.showDebug(TAG, `getFilesDir File directory obtained. Data: ${JSON.stringify(data)}`);
416e80583aSopenharmony_ci        this.baseDir = data + '/';
426e80583aSopenharmony_ci      }).catch((error) => {
436e80583aSopenharmony_ci        Log.showError(TAG, `getFilesDir Failed to obtain the file directory. Cause: ${JSON.stringify(error)}`);
446e80583aSopenharmony_ci      });
456e80583aSopenharmony_ci  }
466e80583aSopenharmony_ci
476e80583aSopenharmony_ci  async getFileContent(fpath: string): Promise<string> {
486e80583aSopenharmony_ci    if (this.baseDir == undefined) {
496e80583aSopenharmony_ci      await this.getBaseDir();
506e80583aSopenharmony_ci    }
516e80583aSopenharmony_ci    Log.showDebug(TAG, `getFileContent fpath: ${fpath}`);
526e80583aSopenharmony_ci    const fd = fileIo.openSync(fpath, 0o2);
536e80583aSopenharmony_ci    const content = this.getContent(fd);
546e80583aSopenharmony_ci    fileIo.closeSync(fd);
556e80583aSopenharmony_ci    return content;
566e80583aSopenharmony_ci  }
576e80583aSopenharmony_ci
586e80583aSopenharmony_ci  private getContent(fd): string {
596e80583aSopenharmony_ci    const bufArray = [];
606e80583aSopenharmony_ci    let totalLength = 0;
616e80583aSopenharmony_ci    let buf = new ArrayBuffer(READ_DATA_SIZE);
626e80583aSopenharmony_ci    let len = fileIo.readSync(fd, buf);
636e80583aSopenharmony_ci    while (len != 0) {
646e80583aSopenharmony_ci      Log.showDebug(TAG, `getContent fileIo reading ${len}`);
656e80583aSopenharmony_ci      totalLength += len;
666e80583aSopenharmony_ci      if (len < READ_DATA_SIZE) {
676e80583aSopenharmony_ci        buf = buf.slice(0, len);
686e80583aSopenharmony_ci        bufArray.push(buf);
696e80583aSopenharmony_ci        break;
706e80583aSopenharmony_ci      }
716e80583aSopenharmony_ci      bufArray.push(buf);
726e80583aSopenharmony_ci      buf = new ArrayBuffer(READ_DATA_SIZE);
736e80583aSopenharmony_ci      len = fileIo.readSync(fd, buf);
746e80583aSopenharmony_ci    }
756e80583aSopenharmony_ci    Log.showDebug(TAG, `getContent read finished ${totalLength}`);
766e80583aSopenharmony_ci    const contentBuf = new Uint8Array(totalLength);
776e80583aSopenharmony_ci    let offset = 0;
786e80583aSopenharmony_ci    for (const bufArr of bufArray) {
796e80583aSopenharmony_ci      Log.showDebug(TAG, `getContent collecting ${offset}`);
806e80583aSopenharmony_ci      const uInt8Arr = new Uint8Array(bufArr);
816e80583aSopenharmony_ci      contentBuf.set(uInt8Arr, offset);
826e80583aSopenharmony_ci      offset += uInt8Arr.byteLength;
836e80583aSopenharmony_ci    }
846e80583aSopenharmony_ci    const content = String.fromCharCode.apply(null, new Uint8Array(contentBuf));
856e80583aSopenharmony_ci    return content;
866e80583aSopenharmony_ci  }
876e80583aSopenharmony_ci
886e80583aSopenharmony_ci  writeToFile(fpath: string, content: string): void {
896e80583aSopenharmony_ci    if (this.baseDir == undefined) {
906e80583aSopenharmony_ci      this.getBaseDir();
916e80583aSopenharmony_ci    }
926e80583aSopenharmony_ci    const fd = fileIo.openSync(this.baseDir + fpath, 0o102, 0o666);
936e80583aSopenharmony_ci    fileIo.writeSync(fd, content);
946e80583aSopenharmony_ci    fileIo.closeSync(fd);
956e80583aSopenharmony_ci  }
966e80583aSopenharmony_ci}