Skip to content

Commit bdc1c59

Browse files
committed
feat: 优化二进制的检测
1 parent 8b20f51 commit bdc1c59

File tree

3 files changed

+37
-20
lines changed

3 files changed

+37
-20
lines changed

frontend/src/hooks/useCode.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { LANG_MAP } from '@/utils/option'
66
import { getEncodeValue, readPath, saveFile } from '@/utils/file'
77

88
import { useUserStore } from '@/store/user'
9-
// import { useOpenStore } from '@/store/open'
9+
import { useOpenStore } from '@/store/open'
1010

1111
interface OptionModel {
1212
confirm: () => boolean
@@ -26,7 +26,7 @@ interface CodeModel {
2626
}
2727

2828
export default function useCode(option: OptionModel) {
29-
// const open = useOpenStore()
29+
const open = useOpenStore()
3030
const user = useUserStore()
3131

3232
const code = reactive<CodeModel>({
@@ -53,14 +53,15 @@ export default function useCode(option: OptionModel) {
5353
code.date = date
5454

5555
const info = getEncodeValue(code.buffer)
56-
code.encode = info.encode
57-
code.org = code.value = info.value
58-
59-
// if (await isBinaryContent(data)) {
60-
// option.onError('不支持二进制文件的编辑')
61-
// open.removeHistory(path)
62-
// return
63-
// }
56+
57+
if (info.encode) {
58+
code.encode = info.encode
59+
code.org = code.value = info.value
60+
} else {
61+
option.onError('不支持二进制文件的编辑')
62+
open.removeHistory(path)
63+
return
64+
}
6465

6566
const filename = path.split('/').pop() || ''
6667

frontend/src/utils/file.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,15 @@ export const getKey = (path: string) =>
5454
.replace(/\./g, '_')
5555

5656
export const getEncodeValue = (buffer: ArrayBuffer) => {
57-
let encode = 'utf-8'
57+
// 取前 1M 的文件进行编码判断
58+
const match = buffer.slice(0, 1024 * 1024)
59+
60+
let encode = ''
5861

5962
for (const item of ENCODING_OPTIONS) {
6063
try {
6164
const decoder = new TextDecoder(item.value)
62-
const text = decoder.decode(buffer)
65+
const text = decoder.decode(match)
6366

6467
if (text.includes('�')) {
6568
continue
@@ -78,7 +81,26 @@ export const getEncodeValue = (buffer: ArrayBuffer) => {
7881
}
7982
}
8083

81-
return { encode, value: new TextDecoder(encode).decode(buffer) }
84+
if (!encode && !isBinaryContent(buffer)) {
85+
encode = 'utf-8'
86+
}
87+
88+
return { encode, value: encode ? new TextDecoder(encode).decode(buffer) : '' }
89+
}
90+
91+
export const isBinaryContent = (buffer: ArrayBuffer) => {
92+
const bytes = new Uint8Array(buffer)
93+
94+
if (bytes.length === 0) {
95+
return false
96+
}
97+
98+
// 检查是否有 null 字节(文本文件中罕见)
99+
if (bytes.includes(0)) {
100+
return true
101+
}
102+
103+
return bytes.reduce((sum, i) => sum + Number(i && i < 32 && i !== 9 && i !== 10 && i !== 13), 0) / bytes.length > 0.1
82104
}
83105

84106
export const readPath = async <T = any>(opt: { path: string; responseType?: 'json' | 'arraybuffer' | 'text'; dir?: boolean }) => {

frontend/src/utils/option.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export const THEME_OPTIONS: { label: string; value: string; dark: boolean }[] =
8787
const codeMatch = (v: string) => {
8888
const sum = v.length
8989
const err = v.split('').filter((i) => i.charCodeAt(0) > 191).length
90-
return err / sum < 0.1
90+
return err / sum < 0.05
9191
}
9292

9393
export const ENCODING_OPTIONS = [
@@ -105,10 +105,4 @@ export const ENCODING_OPTIONS = [
105105
{ value: 'ascii', label: 'ASCII', match: codeMatch },
106106
{ value: 'latin1', label: 'ISO-8859-1', match: codeMatch },
107107
{ value: 'windows-1252', label: 'Windows-1252', match: codeMatch },
108-
109-
// 日韩编码
110-
{ value: 'shift_jis', label: 'Shift_JIS' },
111-
{ value: 'euc-jp', label: 'EUC-JP' },
112-
{ value: 'euc-kr', label: 'EUC-KR' },
113-
{ value: 'windows-949', label: 'Windows-949' },
114108
]

0 commit comments

Comments
 (0)