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()