- Mở và đóng tệp Thư viện os trong Go cung cấp hàm os.Open() để mở một tệp, trả về một con trỏ *File và một lỗi (nếu có). Sau khi hoàn tất thao tác với đối tượng tệp, bạn phải nhớ đóng tệp bằng cách gọi phương thức Close().
package main
import (
"fmt"
"os"
)
func main() {
// Mở tệp main.go ở chế độ chỉ đọc
tap_tin, loi := os.Open("./main.go")
if loi != nil {
fmt.Println("Không thể mở tệp, lỗi:", loi)
return
}
fmt.Println(tap_tin) // &{0xc000078780}
defer tap_tin.Close() // Đóng tệp khi hàm kết thúc
}
Việc sử dụng defer để đăng ký câu lệnh đóng tệp là một thực hành tốt để đảm bảo tệp luôn được đóng, ngay cả khi có lỗi xảy ra.
- Đọc tệp
2.1. Sử dụng cơ bản file.Read() Phương thức Read được định nghĩa như sau:
func (f *File) Read(b []byte) (n int, err error)
Nó nhận một lát byte (slice) và trả về số byte đã đọc và một lỗi cụ thể. Khi đọc đến cuối tệp, nó sẽ trả về 0 và io.EOF.
package main
import (
"fmt"
"io"
"os"
)
func main() {
tap_tin, loi := os.Open("./main.go")
if loi != nil {
fmt.Println("Không thể mở tệp, lỗi:", loi)
return
}
defer tap_tin.Close()
var bo_nho_tam = make([]byte, 128)
n, loi := tap_tin.Read(bo_nho_tam)
if loi == io.EOF {
fmt.Println("Đã đọc hết tệp")
return
}
if loi != nil {
fmt.Println("Đọc tệp thất bại, lỗi:", loi)
return
}
fmt.Printf("Đã đọc %d byte dữ liệu
", n)
fmt.Println(string(bo_nho_tam[:n])) // Cắt dữ liệu từ đầu đến n
}
2.2. Đọc tệp bằng vòng lặp
Sử dụng vòng lặp for để đọc toàn bộ dữ liệu trong tệp.
package main
import (
"fmt"
"os"
)
func main() {
tap_tin, loi := os.Open("./main.go")
if loi != nil {
fmt.Println("Không thể mở tệp, lỗi:", loi)
return
}
defer tap_tin.Close()
var noi_dung []byte
var bo_nho_tam = make([]byte, 128)
for {
n, loi := tap_tin.Read(bo_nho_tam)
if loi == io.EOF {
fmt.Println("Đã đọc hết tệp")
break
}
if loi != nil {
fmt.Println("Đọc tệp thất bại, lỗi:", loi)
return
}
noi_dung = append(noi_dung, bo_nho_tam[:n]...)
}
fmt.Println(string(noi_dung))
}
2.3. Đọc tệp bằng bufio bufio là một lớp API được đóng gói trên file, hỗ trợ nhiều chức năng hơn, ví dụ như đọc theo dòng.
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
tap_tin, loi := os.Open("C:/test.txt")
if loi != nil {
fmt.Println("Không thể mở tệp, lỗi:", loi)
return
}
defer tap_tin.Close()
doc_doc = bufio.NewReader(tap_tin)
for {
dong, loi := doc_doc.ReadString('
') // Đọc đến ký tự xuống dòng
if loi == io.EOF {
if len(dong) != 0 {
fmt.Println("Vẫn còn dữ liệu chưa đọc", dong)
}
fmt.Println("Đã đọc hết tệp")
break
}
if loi != nil {
fmt.Println("Đọc tệp thất bại, lỗi:", loi)
return
}
fmt.Print(dong)
}
}
2.4. Đọc toàn bộ tệp bằng ioutil Gói io/ioutil cung cấp hàm ReadFile để đọc toàn bộ nội dung tệp chỉ với một dòng lệnh.
package main
import (
"fmt"
"io/ioutil"
)
func main() {
noi_dung, loi := ioutil.ReadFile("./main.go")
if loi != nil {
fmt.Println("Đọc tệp thất bại, lỗi:", loi)
return
}
fmt.Println(string(noi_dung)) // Chuyển đổi nội dung sang chuỗi để hiển thị
}
- Ghi tệp Hàm os.OpenFile() cho phép mở tệp với các chế độ khác nhau để thực hiện ghi.
func OpenFile(name string, flag int, perm FileMode) (*File, error)
Trong đó:
name: Tên tệp.flag: Chế độ mở tệp.os.O_WRONLY: Chỉ ghi.os.O_CREATE: Tạo tệp nếu chưa tồn tại.os.O_RDONLY: Chỉ đọc.os.O_RDWR: Đọc và ghi.os.O_TRUNC: Xóa nội dung tệp.os.O_APPEND: Ghi thêm vào cuối.perm: Quyền tệp, là một số bát phân (ví dụ:0666cho đọc và ghi).
3.1. Write và WriteString
package main
import (
"fmt"
"os"
)
func main() {
tap_tin, loi := os.OpenFile("C:/test.txt", os.O_CREATE|os.O_RDWR, 0666)
if loi != nil {
fmt.Println("Không thể mở tệp, lỗi:", loi)
return
}
defer tap_tin.Close()
chuoi := "Xin chào Go"
tap_tin.Write([]byte(chuoi)) // Ghi dữ liệu từ lát byte
tap_tin.WriteString("Dữ liệu chuỗi được ghi trực tiếp") // Ghi chuỗi trực tiếp
}
3.2. bufio.NewWriter
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
tap_tin, loi := os.OpenFile("C:/test.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if loi != nil {
fmt.Println("Không thể mở tệp, lỗi:", loi)
return
}
defer tap_tin.Close()
viet_vao = bufio.NewWriter(tap_tin)
for i := 0; i < 10; i++ {
viet_vao.WriteString("Xin chào Go \r
") // Ghi dữ liệu vào bộ đệm
}
viet_vao.Flush() // Ghi dữ liệu từ bộ đệm vào tệp (quan trọng)
}
3.3. ioutil.WriteFile
package main
import (
"fmt"
"io/ioutil"
)
func main() {
chuoi := "hello golang"
loi := ioutil.WriteFile("C:/test.txt", []byte(chuoi), 0666)
if loi != nil {
fmt.Println("Ghi tệp thất bại, lỗi:", loi)
return
}
}
- Đổi tên tệp Lưu ý: Hoạt động đổi tên bằng os.Rename() chỉ có thể thực hiện trong cùng một ổ đĩa.
loi := os.Rename("C:/test.txt", "C:/test001.txt")
if loi != nil {
fmt.Println(loi)
}
- Sao chép tệp
5.1. Phương pháp sử dụng ioutil
package main
import (
"fmt"
"io/ioutil"
)
// Hàm sao chép tệp, nhận đường dẫn nguồn và đích
func SaoChepTep(duong_dan_dich string, duong_dan_nguon string) (loi error) {
du_lieu_nguon, loi := ioutil.ReadFile(duong_dan_nguon)
if loi != nil {
fmt.Println(loi)
return loi
}
loi = ioutil.WriteFile(duong_dan_dich, du_lieu_nguon, 0644)
if loi != nil {
fmt.Println("Lỗi khi tạo", duong_dan_dich)
fmt.Println(loi)
return loi
}
return nil
}
func main() {
tap_tin_nguon := "C:/test1.zip"
tap_tin_dich := "D:/test.gz"
loi := SaoChepTep(tap_tin_dich, tap_tin_nguon)
if loi == nil {
fmt.Printf("Sao chép hoàn tất
")
} else {
fmt.Printf("Lỗi sao chép err=%v
", loi)
}
}
5.2. Phương pháp sử dụng luồng (stream)
package main
import (
"fmt"
"io"
"os"
)
// Hàm sao chép tệp bằng luồng
func SaoChepTepLuong(duong_dan_dich string, duong_dan_nguon string) (loi error) {
nguon, _ := os.Open(duong_dan_nguon)
dich, _ := os.OpenFile(duong_dan_dich, os.O_CREATE|os.O_WRONLY, 0666)
buf := make([]byte, 128)
for {
n, loi := nguon.Read(buf)
if loi != nil && loi != io.EOF {
fmt.Println("Tệp chưa được đọc hết")
return loi
}
if n == 0 {
break
}
if _, loi := dich.Write(buf[:n]); loi != nil {
return loi
}
}
return nil
}
func main() {
tap_tin_nguon := "C:/000.avi"
tap_tin_dich := "D:/000111.avi"
loi := SaoChepTepLuong(tap_tin_dich, tap_tin_nguon)
if loi == nil {
fmt.Printf("Sao chép hoàn tất
")
} else {
fmt.Printf("Lỗi sao chép err=%v
", loi)
}
}
- Tạo thư mục
6.1. Tạo một thư mục
loi := os.Mkdir("./thu_muc_moi", 0666)
if loi != nil {
fmt.Println(loi)
}
6.2. Tạo nhiều thư mục cùng lúc
loi := os.MkdirAll("thu_muc1/thu_muc2/thu_muc3", 0666) // Tạo thư mục lồng nhau
if loi != nil {
fmt.Println(loi)
}
- Xóa tệp và thư mục
7.1. Xóa một tệp hoặc thư mục
loi := os.Remove("./main.go")
if loi != nil {
fmt.Println(loi)
}
7.2. Xóa nhiều tệp hoặc thư mục
loi := os.RemoveAll("thu_muc_can_xoa")
if loi != nil {
fmt.Println(loi)
}