const getFileExtension = (filename: string) => { return filename.split('.').pop(); }; const getFileType = (extension: string) => { switch (extension) { case 'js': return 'text/javascript'; case 'css': return 'text/css'; case 'html': return 'text/html'; case 'json': return 'application/json'; case 'png': return 'image/png'; case 'jpg': return 'image/jpeg'; case 'jpeg': return 'image/jpeg'; case 'gif': return 'image/gif'; case 'svg': return 'image/svg+xml'; case 'webp': return 'image/webp'; case 'ico': return 'image/x-icon'; default: return 'text/plain'; } }; const checkIsBase64 = (content: string) => { return content.startsWith('data:'); }; /** * 获取文件的目录和文件名 * @param filename 文件名 * @returns 目录和文件名 */ export const getDirectoryAndName = (filename: string) => { if (!filename) { return null; } if (filename.startsWith('.')) { return null; } else { filename = filename.replace(/^\/+/, ''); // Remove all leading slashes } const hasDirectory = filename.includes('/'); if (!hasDirectory) { return { directory: '', name: filename }; } const parts = filename.split('/'); const name = parts.pop()!; // Get the last part as the file name const directory = parts.join('/'); // Join the remaining parts as the directory return { directory, name }; }; /** * 把字符串转为文件流,并返回文件流,根据filename的扩展名,自动设置文件类型. * 当不是文本类型,自动需要把base64的字符串转为blob * @param content 字符串 * @param filename 文件名 * @returns 文件流 */ export const toFile = (content: string, filename: string) => { // 如果文件名是 a/d/a.js 格式的,则需要把d作为目录,a.js作为文件名 const directoryAndName = getDirectoryAndName(filename); if (!directoryAndName) { throw new Error('Invalid filename'); } const { name } = directoryAndName; const extension = getFileExtension(name); if (!extension) { throw new Error('Invalid filename'); } const isBase64 = checkIsBase64(content); const type = getFileType(extension); if (isBase64) { // Decode base64 string const base64Data = content.split(',')[1]; // Remove the data URL prefix const byteCharacters = atob(base64Data); const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); const blob = new Blob([byteArray], { type }); return new File([blob], filename, { type }); } else { const blob = new Blob([content], { type }); return new File([blob], filename, { type }); } }; /** * 把字符串转为文本文件 * @param content 字符串 * @param filename 文件名 * @returns 文件流 */ export const toTextFile = (content: string = 'keep directory exist', filename: string = 'keep.txt') => { const file = toFile(content, filename); return file; };