1import pathConst from '@/constants/pathConst'; 2import FastImage from 'react-native-fast-image'; 3import RNFS, { 4 copyFile, 5 downloadFile, 6 exists, 7 mkdir, 8 PicturesDirectoryPath, 9 readDir, 10 unlink, 11 writeFile, 12} from 'react-native-fs'; 13import {errorLog} from './log'; 14import path from 'path-browserify'; 15 16export const galleryBasePath = `${PicturesDirectoryPath}/MusicFree/`; 17 18export async function saveToGallery(src: string) { 19 const fileName = `${galleryBasePath}${Date.now()}.png`; 20 if (!(await exists(galleryBasePath))) { 21 await mkdir(galleryBasePath); 22 } 23 if (await exists(src)) { 24 try { 25 await copyFile(src, fileName); 26 } catch (e) { 27 console.log('... ', e); 28 } 29 } 30 if (src.startsWith('http')) { 31 await downloadFile({ 32 fromUrl: src, 33 toFile: fileName, 34 background: true, 35 }); 36 } 37 if (src.startsWith('data')) { 38 await writeFile(fileName, src); 39 } 40} 41 42export function sizeFormatter(bytes: number | string) { 43 if (typeof bytes === 'string') { 44 return bytes; 45 } 46 if (bytes === 0) { 47 return '0B'; 48 } 49 let k = 1024, 50 sizes = ['B', 'KB', 'MB', 'GB'], 51 i = Math.floor(Math.log(bytes) / Math.log(k)); 52 return (bytes / Math.pow(k, i)).toFixed(1) + sizes[i]; 53} 54 55export async function checkAndCreateDir(dirPath: string) { 56 const filePath = dirPath; 57 try { 58 if (!(await exists(filePath))) { 59 await mkdir(filePath); 60 } 61 } catch (e) { 62 errorLog('无法初始化目录', {path: dirPath, e}); 63 } 64} 65 66async function getFolderSize(dirPath: string): Promise<number> { 67 let size = 0; 68 try { 69 const fns = await readDir(dirPath); 70 for (let fn of fns) { 71 if (fn.isFile()) { 72 size += fn.size; 73 } 74 // todo: 可以改成并行 promise.all 75 if (fn.isDirectory()) { 76 size += await getFolderSize(fn.path); 77 } 78 } 79 } catch {} 80 return size; 81} 82 83export async function getCacheSize( 84 type: 'music' | 'lyric' | 'image', 85): Promise<number> { 86 if (type === 'music') { 87 return getFolderSize(pathConst.musicCachePath); 88 } else if (type === 'lyric') { 89 return getFolderSize(pathConst.lrcCachePath); 90 } else if (type === 'image') { 91 return getFolderSize(pathConst.imageCachePath); 92 } 93 throw new Error(); 94} 95 96export async function clearCache(type: 'music' | 'lyric' | 'image') { 97 if (type === 'music') { 98 try { 99 if (await exists(pathConst.musicCachePath)) { 100 return unlink(pathConst.musicCachePath); 101 } 102 } catch {} 103 } else if (type === 'lyric') { 104 try { 105 const lrcs = readDir(pathConst.lrcCachePath); 106 return Promise.all((await lrcs).map(_ => unlink(_.path))); 107 } catch {} 108 } else if (type === 'image') { 109 return FastImage.clearDiskCache(); 110 } 111} 112 113export function addFileScheme(fileName: string) { 114 if (fileName.startsWith('/')) { 115 return `file://${fileName}`; 116 } 117 return fileName; 118} 119 120export function addRandomHash(url: string) { 121 if (url.indexOf('#') === -1) { 122 return `${url}#${Date.now()}`; 123 } 124 return url; 125} 126 127export function trimHash(url: string) { 128 const index = url.lastIndexOf('#'); 129 if (index === -1) { 130 return url; 131 } 132 return url.substring(0, index); 133} 134 135export function escapeCharacter(str?: string) { 136 return str !== undefined ? `${str}`.replace(/[/|\\?*"<>:]+/g, '_') : ''; 137} 138 139export function getDirectory(dirPath: string) { 140 const lastSlash = dirPath.lastIndexOf('/'); 141 if (lastSlash === -1) { 142 return dirPath; 143 } 144 return dirPath.slice(0, lastSlash); 145} 146 147export function getFileName(filePath: string, withoutExt?: boolean) { 148 const lastSlash = filePath.lastIndexOf('/'); 149 if (lastSlash === -1) { 150 return filePath; 151 } 152 let fileName = filePath.slice(lastSlash + 1); 153 if (withoutExt) { 154 const lastDot = fileName.lastIndexOf('.'); 155 fileName = lastDot === -1 ? fileName : fileName.slice(0, lastDot); 156 } 157 158 try { 159 return decodeURIComponent(fileName); 160 } catch { 161 return fileName; 162 } 163} 164 165export async function mkdirR(directory: string) { 166 let folder = directory; 167 const checkStack: string[] = []; 168 while (folder.length > 15) { 169 checkStack.push(folder); 170 folder = path.dirname(folder); 171 } 172 let existPos = 0; 173 for (let i = 0; i < checkStack.length; ++i) { 174 const isExist = await exists(checkStack[i]); 175 if (isExist) { 176 existPos = i; 177 break; 178 } 179 } 180 181 for (let j = existPos - 1; j >= 0; --j) { 182 try { 183 await mkdir(checkStack[j]); 184 } catch (e) { 185 console.log('error', e); 186 } 187 } 188} 189 190export async function writeInChunks( 191 filePath: string, 192 data, 193 chunkSize = 1024 * 1024 * 2, 194) { 195 let offset = 0; 196 console.log('here'); 197 if (await exists(filePath)) { 198 await unlink(filePath); 199 } 200 201 while (offset < data.length) { 202 const chunk = data.slice(offset, offset + chunkSize); 203 if (offset === 0) { 204 await RNFS.writeFile(filePath, chunk, 'utf8'); 205 } else { 206 await RNFS.appendFile(filePath, chunk, 'utf8'); 207 } 208 offset += chunkSize; 209 } 210} 211