Các thao tác tệp và thư mục trong ngôn ngữ Go

  1. 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.

  1. Đọ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ị
}
  1. 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ụ: 0666 cho đọ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
	}
}
  1. Đổ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)
}
  1. 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)
	}
}
  1. 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)
}
  1. 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)
}

Thẻ: Go os file directory bufio

Đăng vào ngày 7 tháng 6 lúc 20:33