• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 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 storageStatistics from '@ohos.file.storageStatistics'
17import fileio from '@ohos.fileio'
18import Logger from '../../utils/Logger'
19import { FileType, SubDirectoryType } from '../../mock/local/FileData'
20import prompt from '@ohos.promptAction'
21
22// 大小和单位
23const GB_MAGNITUDE: number = 1024 * 1024 * 1024
24const MB_MAGNITUDE: number = 1024 * 1024
25const KB_MAGNITUDE: number = 1024
26const GB_SYMBOL: string = 'GB'
27const MB_SYMBOL: string = 'MB'
28const KB_SYMBOL: string = 'KB'
29const BYTE_SYMBOL: string = 'B'
30
31class FileSystem {
32  // 总空间---默认GB
33  async getTotalSize(): Promise<string> {
34    let totalSize: number = await storageStatistics.getTotalSize()
35    // 处理大小
36    return `${(totalSize / GB_MAGNITUDE).toFixed(2)}${GB_SYMBOL}`
37  }
38
39  // 剩余空间
40  async getFreeSize(): Promise<string> {
41    let freeSize = await storageStatistics.getFreeSize()
42    if (freeSize / GB_MAGNITUDE > 1) {
43      return `${(freeSize / GB_MAGNITUDE).toFixed(2)}${GB_SYMBOL}`
44    } else if (freeSize / MB_MAGNITUDE > 1) {
45      return `${(freeSize / MB_MAGNITUDE).toFixed(2)}${MB_SYMBOL}`
46    } else if (freeSize / KB_MAGNITUDE > 1) {
47      return `${(freeSize / KB_MAGNITUDE).toFixed(2)}${KB_SYMBOL}`
48    } else {
49      return `${freeSize}${BYTE_SYMBOL}`
50    }
51  }
52
53  // 根据沙箱路径打开目录
54  getSubdirectory(filePath: string): Array<SubDirectoryType> {
55    // 获取目录
56    let dir = fileio.opendirSync(filePath)
57    // 读取的结果
58    let dirent
59    // 结果数组
60    let subdirectory = []
61    do {
62      dirent = dir.readSync()
63      if (dirent) {
64        let subdirectoryNum = 0
65        let fileSize = ''
66        let time = new Date()
67        // 如果是文件夹,就读取文件夹中文件的数量
68        if (dirent.isDirectory()) {
69          subdirectoryNum = this.getSubdirectoryNum(filePath + `${dirent.name}`)
70        } else {
71          // 如果不是问价夹,就读取文件大小和时间
72          fileSize = this.getFileSize(filePath + `${dirent.name}`)
73          time = this.getFileTime(filePath + `${dirent.name}`)
74        }
75        subdirectory.push({
76          name: dirent.name,
77          type: dirent.isDirectory() ? 1 : 2,
78          time,
79          childrenNum: subdirectoryNum,
80          fileSize
81        })
82      }
83    } while (dirent)
84    return subdirectory
85  }
86
87  // 获取目录中的子目录个数
88  getSubdirectoryNum(filePath: string): number {
89    let dir = fileio.opendirSync(filePath)
90    // 读取的结果
91    let dirent
92    // 记录子目录的个数
93    let subdirectoryNum = 0
94    do {
95      dirent = dir.readSync()
96      if (dirent) {
97        subdirectoryNum++
98      }
99    } while (dirent)
100    return subdirectoryNum
101  }
102
103  // 获取文件大小
104  getFileSize(filePath: string): string {
105    try {
106      let fileSize = fileio.statSync(filePath).size
107      if (fileSize / GB_MAGNITUDE > 1) {
108        return `${(fileSize / GB_MAGNITUDE).toFixed(2)}${GB_SYMBOL}`
109      } else if (fileSize / MB_MAGNITUDE > 1) {
110        return `${(fileSize / MB_MAGNITUDE).toFixed(2)}${MB_SYMBOL}`
111      } else if (fileSize / KB_MAGNITUDE > 1) {
112        return `${(fileSize / KB_MAGNITUDE).toFixed(2)}${KB_SYMBOL}`
113      } else {
114        return `${fileSize}${BYTE_SYMBOL}`
115      }
116    } catch (err) {
117      Logger.error(`getFileSize failed,code is ${err.code}, message is ${err.message}`)
118    }
119  }
120
121  // 获取文件修改时间
122  getFileTime(filePath: string): Date {
123    try {
124      let fileTime = fileio.statSync(filePath).ctime
125      return new Date(fileTime * 1000)
126    } catch (err) {
127      Logger.error(`getFileTime failed,code is ${err.code}, message is ${err.message}`)
128    }
129  }
130
131  // 创建目录
132  createDirectory(filePath: string): void {
133    try {
134      fileio.mkdirSync(filePath)
135    } catch (err) {
136      Logger.error(`create directory failed, code is ${err.code}, message is ${err.message}`)
137    }
138  }
139
140  // 创建文件
141  createFile(filePath: string): void {
142    try {
143      fileio.openSync(filePath, 0o100, 0o666)
144    } catch (err) {
145      Logger.error(`create file failed, code is ${err.code}, message is ${err.message}`)
146    }
147  }
148
149  // 删除目录和文件---选中项
150  deleteSelected(dataArray: Map<string, number>): void {
151    try {
152      // 遍历数据,分别调用对应的api删除数据
153      for (let data of dataArray) {
154        if (data[1] === 1) {
155          fileio.rmdirSync(data[0])
156        } else {
157          fileio.unlinkSync(data[0])
158        }
159      }
160      prompt.showToast({ message: $r('app.string.label_delete_success') })
161    } catch (err) {
162      Logger.error(`delete failed, code is ${err.code}, message is ${err.message}`)
163    }
164  }
165
166  // 复制文件
167  copyFile(filePath: string, newFilePath: string): void {
168    try {
169      // 遍历数据直接copy所有项目
170      fileio.copyFileSync(filePath, newFilePath)
171    } catch (err) {
172      Logger.error(`copy file failed, code is ${err.code}, message is ${err.message}`)
173    }
174  }
175
176  // 重命名文件
177  renameFile(filePath: string, newFilePath: string): void {
178    try {
179      fileio.renameSync(filePath, newFilePath)
180    } catch (err) {
181      Logger.error(`rename file failed, code is ${err.code}, message is ${err.message}`)
182    }
183  }
184
185  // 开始移动文件
186  startMoveFile(needMoveFiles: Array<FileType>, newFilePath: string): void {
187    // 遍历数据
188    needMoveFiles.forEach((file: FileType): void => {
189      // 如果是目录
190      if (file.type === 1) {
191        // 先创建这个目录
192        this.createDirectory(`${newFilePath}/${file.fileName}`)
193        // 获取当前文件夹下的所有文件目录
194        let subdirectory = this.getSubdirectory(`${file.filePath}/`)
195        // 处理为我们想要的格式
196        let needMoveFiles: Array<FileType> = []
197        // 遍历子目录数据
198        subdirectory.forEach((subdirectoryData: SubDirectoryType) => {
199          let data = {
200            filePath: `${file.filePath}/${subdirectoryData.name}`,
201            fileName: subdirectoryData.name,
202            type: subdirectoryData.type
203          }
204          // 逐一添加进去
205          needMoveFiles.push(data)
206        })
207        // 使用我们的数据递归
208        this.startMoveFile(needMoveFiles, `${newFilePath}/${file.fileName}`)
209      } else {
210        this.copyFile(file.filePath, `${newFilePath}/${file.fileName}`)
211      }
212    })
213  }
214}
215
216export default new FileSystem()