forked from gookit/goutil
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopwrite.go
182 lines (161 loc) · 4.6 KB
/
opwrite.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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package fsutil
import (
"io"
"os"
"github.com/gookit/goutil/basefn"
)
// ************************************************************
// temp file or dir
// ************************************************************
// OSTempFile create a temp file on os.TempDir()
//
// Usage:
//
// fsutil.OSTempFile("example.*.txt")
func OSTempFile(pattern string) (*os.File, error) {
return os.CreateTemp(os.TempDir(), pattern)
}
// TempFile is like os.CreateTemp, but can custom temp dir.
//
// Usage:
//
// // create temp file on os.TempDir()
// fsutil.TempFile("", "example.*.txt")
// // create temp file on "testdata" dir
// fsutil.TempFile("testdata", "example.*.txt")
func TempFile(dir, pattern string) (*os.File, error) {
return os.CreateTemp(dir, pattern)
}
// OSTempDir creates a new temp dir on os.TempDir and return the temp dir path
//
// Usage:
//
// fsutil.OSTempDir("example.*")
func OSTempDir(pattern string) (string, error) {
return os.MkdirTemp(os.TempDir(), pattern)
}
// TempDir creates a new temp dir and return the temp dir path
//
// Usage:
//
// fsutil.TempDir("", "example.*")
// fsutil.TempDir("testdata", "example.*")
func TempDir(dir, pattern string) (string, error) {
return os.MkdirTemp(dir, pattern)
}
// ************************************************************
// write, copy files
// ************************************************************
// MustSave create file and write contents to file, panic on error.
//
// - data type allow: string, []byte, io.Reader
//
// default option see NewOpenOption()
func MustSave(filePath string, data any, optFns ...OpenOptionFunc) {
basefn.MustOK(SaveFile(filePath, data, optFns...))
}
// SaveFile create file and write contents to file. will auto create dir.
//
// - data type allow: string, []byte, io.Reader
//
// default option see NewOpenOption()
func SaveFile(filePath string, data any, optFns ...OpenOptionFunc) error {
opt := NewOpenOption(optFns...)
return WriteFile(filePath, data, opt.Perm, opt.Flag)
}
// PutContents create file and write contents to file at once.
//
// data type allow: string, []byte, io.Reader. will auto create dir.
//
// Tip: file flag default is FsCWTFlags (override write)
//
// Usage:
//
// fsutil.PutContents(filePath, contents, fsutil.FsCWAFlags) // append write
// fsutil.Must2(fsutil.PutContents(filePath, contents)) // panic on error
func PutContents(filePath string, data any, fileFlag ...int) (int, error) {
f, err := QuickOpenFile(filePath, basefn.FirstOr(fileFlag, FsCWTFlags))
if err != nil {
return 0, err
}
return WriteOSFile(f, data)
}
// WriteFile create file and write contents to file, can set perm for file.
//
// data type allow: string, []byte, io.Reader
//
// Tip: file flag default is FsCWTFlags (override write)
//
// Usage:
//
// fsutil.WriteFile(filePath, contents, fsutil.DefaultFilePerm, fsutil.FsCWAFlags)
func WriteFile(filePath string, data any, perm os.FileMode, fileFlag ...int) error {
flag := basefn.FirstOr(fileFlag, FsCWTFlags)
f, err := OpenFile(filePath, flag, perm)
if err != nil {
return err
}
_, err = WriteOSFile(f, data)
return err
}
// WriteOSFile write data to give os.File, then close file.
//
// data type allow: string, []byte, io.Reader
func WriteOSFile(f *os.File, data any) (n int, err error) {
switch typData := data.(type) {
case []byte:
n, err = f.Write(typData)
case string:
n, err = f.WriteString(typData)
case io.Reader: // eg: buffer
var n64 int64
n64, err = io.Copy(f, typData)
n = int(n64)
default:
_ = f.Close()
panic("WriteFile: data type only allow: []byte, string, io.Reader")
}
if err1 := f.Close(); err1 != nil && err == nil {
err = err1
}
return n, err
}
// CopyFile copy a file to another file path.
func CopyFile(srcPath, dstPath string) error {
srcFile, err := os.OpenFile(srcPath, FsRFlags, 0)
if err != nil {
return err
}
defer srcFile.Close()
// create and open file
dstFile, err := QuickOpenFile(dstPath, FsCWTFlags)
if err != nil {
return err
}
defer dstFile.Close()
_, err = io.Copy(dstFile, srcFile)
return err
}
// MustCopyFile copy file to another path.
func MustCopyFile(srcPath, dstPath string) {
err := CopyFile(srcPath, dstPath)
if err != nil {
panic(err)
}
}
// UpdateContents read file contents, call handleFn(contents) handle, then write updated contents to file
func UpdateContents(filePath string, handleFn func(bs []byte) []byte) error {
osFile, err := os.OpenFile(filePath, os.O_RDWR|os.O_TRUNC, 0600)
if err != nil {
return err
}
defer osFile.Close()
// read file contents
if bs, err1 := io.ReadAll(osFile); err1 == nil {
bs = handleFn(bs)
_, err = osFile.Write(bs)
} else {
err = err1
}
return err
}