-
Notifications
You must be signed in to change notification settings - Fork 0
/
file.go
112 lines (93 loc) · 2.54 KB
/
file.go
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
package wcu
import (
"io"
"os"
"path/filepath"
"github.com/askasoft/pango/str"
)
// rc read closer
type rc struct {
r io.Reader
c io.Closer
}
func (rc *rc) Read(p []byte) (n int, err error) {
return rc.r.Read(p)
}
func (rc *rc) Close() error {
return rc.c.Close()
}
// OpenFile use specified charset to open file and return a transformed ReadCloser.
// return (nil, error) if failed to open file or charset is unsupported
func OpenFile(filename string, charset string) (io.ReadCloser, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
r, _, err := Transform(f, charset)
if err != nil {
f.Close()
return nil, err
}
return &rc{r: r, c: f}, nil
}
// ReadFile use specified charset to read file.
// return error if failed to open/read file or charset is unsupported
func ReadFile(filename string, charset string) ([]byte, error) {
wf, err := OpenFile(filename, charset)
if err != nil {
return nil, err
}
defer wf.Close()
return io.ReadAll(wf)
}
func IsHTMLFile(filename string) bool {
ext := filepath.Ext(filename)
html := (str.EqualFold(ext, ".html") || str.EqualFold(ext, ".htm"))
return html
}
// DetectCharsetFile detect file's charset
func DetectCharsetFile(filename string) (string, error) {
fr, err := os.Open(filename)
if err != nil {
return "", err
}
defer fr.Close()
html := IsHTMLFile(filename)
_, cs, err := DetectCharsetReader(fr, html)
return cs, err
}
// DetectAndOpenFile use specified charsets to open file, return (transformed reader, encoding name, error).
// if charsets is not specified, or specified charset is unsupported,
// detect the charset of the file, and open a transformed ReadCloser.
// return (nil, "", err) if failed to open file, charset is unsupported or read error occurred.
func DetectAndOpenFile(filename string, charsets ...string) (io.ReadCloser, string, error) {
f, err := os.Open(filename)
if err != nil {
return nil, "", err
}
for _, cs := range charsets {
if cs != "" {
r, enc, err := Transform(f, cs)
if err == nil {
return &rc{r: r, c: f}, enc, nil
}
}
}
html := IsHTMLFile(filename)
r, enc, err := DetectAndTransform(f, html)
if err != nil {
f.Close()
return nil, enc, err
}
return &rc{r: r, c: f}, enc, nil
}
// DetectAndReadFile detect the charset of the file, and open a transformed ReadCloser
func DetectAndReadFile(filename string, charsets ...string) ([]byte, string, error) {
r, enc, err := DetectAndOpenFile(filename, charsets...)
if err != nil {
return nil, enc, err
}
defer r.Close()
bs, err := io.ReadAll(r)
return bs, enc, err
}