xref: /MusicFree/src/utils/fileUtils.ts (revision 0e4173cd50b15efbe5ce9954996c3697547338df)
1import pathConst from '@/constants/pathConst';
2import FastImage from 'react-native-fast-image';
3import {FileSystem} from 'react-native-file-access';
4import {
5    copyFile,
6    downloadFile,
7    exists,
8    mkdir,
9    PicturesDirectoryPath,
10    readDir,
11    unlink,
12    writeFile,
13} from 'react-native-fs';
14import {errorLog} from './log';
15
16const basePath = `${PicturesDirectoryPath}/MusicFree/`;
17export async function saveToGallery(src: string) {
18    const fileName = `${basePath}${Date.now()}.png`;
19    if (!(await exists(basePath))) {
20        await mkdir(basePath);
21    }
22    if (await exists(src)) {
23        try {
24            await copyFile(src, fileName);
25        } catch (e) {
26            console.log('... ', e);
27        }
28    }
29    if (src.startsWith('http')) {
30        await downloadFile({
31            fromUrl: src,
32            toFile: fileName,
33            background: true,
34        });
35    }
36    if (src.startsWith('data')) {
37        await writeFile(fileName, src);
38    }
39}
40
41export function sizeFormatter(bytes: number) {
42    if (bytes === 0) return '0B';
43    let k = 1024,
44        sizes = ['B', 'KB', 'MB', 'GB'],
45        i = Math.floor(Math.log(bytes) / Math.log(k));
46    return (bytes / Math.pow(k, i)).toFixed(1) + sizes[i];
47}
48
49export async function checkAndCreateDir(path: string) {
50    const filePath = path;
51    try {
52        if (!(await exists(filePath))) {
53            await mkdir(filePath);
54        }
55    } catch (e) {
56        errorLog('无法初始化目录', {path, e});
57    }
58}
59
60async function getFolderSize(path: string): Promise<number> {
61    let size = 0;
62    try {
63        const fns = await readDir(path);
64        for (let fn of fns) {
65            if (fn.isFile()) {
66                size += fn.size;
67            }
68            // todo: 可以改成并行 promise.all
69            if (fn.isDirectory()) {
70                size += await getFolderSize(fn.path);
71            }
72        }
73    } catch {}
74    return size;
75}
76
77export async function getCacheSize(
78    type: 'music' | 'lyric' | 'image',
79): Promise<number> {
80    if (type === 'music') {
81        return getFolderSize(pathConst.musicCachePath);
82    } else if (type === 'lyric') {
83        return getFolderSize(pathConst.lrcCachePath);
84    } else if (type === 'image') {
85        return getFolderSize(pathConst.imageCachePath);
86    }
87    throw new Error();
88}
89
90export async function clearCache(type: 'music' | 'lyric' | 'image') {
91    if (type === 'music') {
92        try {
93            if (await exists(pathConst.musicCachePath)) {
94                return unlink(pathConst.musicCachePath);
95            }
96        } catch {}
97    } else if (type === 'lyric') {
98        try {
99            const lrcs = readDir(pathConst.lrcCachePath);
100            return Promise.all((await lrcs).map(_ => unlink(_.path)));
101        } catch {}
102    } else if (type === 'image') {
103        return FastImage.clearDiskCache();
104    }
105}
106
107export async function fileExists(fileName: string) {
108    if (fileName.startsWith('file://')) {
109        return await exists(fileName);
110    } else if (fileName.startsWith('content://')) {
111        return await FileSystem.exists(fileName);
112    } else {
113        return await exists(fileName);
114    }
115}
116