File size: 4,660 Bytes
e85fa50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/**

 * 文件工具函数,提供文件处理相关的实用方法

 */

/**

 * 将文件转换为Base64编码字符串

 * @param file 文件对象

 * @returns Promise,解析为Base64编码的字符串

 */
export const fileToBase64 = (file: File): Promise<string> => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      
      reader.onload = () => {
        if (typeof reader.result === 'string') {
          // 从data URI中提取Base64部分
          const base64String = reader.result.split(',')[1];
          resolve(base64String);
        } else {
          reject(new Error('读取文件失败'));
        }
      };
      
      reader.onerror = () => {
        reject(new Error('读取文件时发生错误'));
      };
      
      reader.readAsDataURL(file);
    });
  };
  
  /**

   * 将Base64编码字符串转换回Blob对象

   * @param base64 Base64编码的字符串

   * @param mimeType MIME类型

   * @returns Blob对象

   */
  export const base64ToBlob = (base64: string, mimeType: string): Blob => {
    const byteCharacters = atob(base64);
    const byteArrays = [];
    
    for (let offset = 0; offset < byteCharacters.length; offset += 512) {
      const slice = byteCharacters.slice(offset, offset + 512);
      
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      
      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
    
    return new Blob(byteArrays, { type: mimeType });
  };
  
  /**

   * 获取文件扩展名

   * @param fileName 文件名

   * @returns 文件扩展名(小写,不包含点号)

   */
  export const getFileExtension = (fileName: string): string => {
    return fileName.split('.').pop()?.toLowerCase() || '';
  };
  
  /**

   * 根据文件扩展名猜测MIME类型

   * @param fileName 文件名

   * @returns MIME类型

   */
  export const guessMimeType = (fileName: string): string => {
    const extension = getFileExtension(fileName);
    
    const mimeTypes: Record<string, string> = {
      'json': 'application/json',
      'txt': 'text/plain',
      'md': 'text/markdown',
      'dsl': 'application/octet-stream',
      'js': 'application/javascript',
      'ts': 'application/typescript',
      'html': 'text/html',
      'css': 'text/css',
      'csv': 'text/csv',
      'xml': 'application/xml',
      'pdf': 'application/pdf',
      'doc': 'application/msword',
      'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      'xls': 'application/vnd.ms-excel',
      'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'ppt': 'application/vnd.ms-powerpoint',
      'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
      'jpg': 'image/jpeg',
      'jpeg': 'image/jpeg',
      'png': 'image/png',
      'gif': 'image/gif',
      'svg': 'image/svg+xml',
      'zip': 'application/zip',
      'rar': 'application/x-rar-compressed',
      '7z': 'application/x-7z-compressed',
    };
    
    return mimeTypes[extension] || 'application/octet-stream';
  };
  
  /**

   * 格式化文件大小为人类可读格式

   * @param bytes 文件大小(字节)

   * @param decimals 小数位数

   * @returns 格式化后的文件大小字符串

   */
  export const formatFileSize = (bytes: number, decimals: number = 2): string => {
    if (bytes === 0) return '0 Bytes';
    
    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    
    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
  };
  
  /**

   * 检查文件是否为有效的DSL文件类型

   * @param file 文件对象

   * @returns 布尔值,指示文件是否为有效的DSL文件类型

   */
  export const isValidDslFile = (file: File): boolean => {
    const validExtensions = ['dsl', 'json', 'txt'];
    const extension = getFileExtension(file.name);
    
    return validExtensions.includes(extension);
  };
  
  /**

   * 安全的文件名生成(移除不安全字符)

   * @param fileName 原始文件名

   * @returns 安全的文件名

   */
  export const sanitizeFileName = (fileName: string): string => {
    // 移除文件名中的不安全字符
    return fileName.replace(/[\\/:*?"<>|]/g, '_');
  };