1. พื้นฐานของไลบรารี OS
แพ็คเกจ os
ใน Golang มีการให้บริการอินเทอร์เฟซที่ไม่ขึ้นอยู่กับแพลตฟอร์มสำหรับฟังก์ชันของระบบปฏิบัติการ ต่อไปนี้เราจะพูดถึงวิธีการใช้แพ็คเกจ os
ในการจัดการเปิดไฟล์ ปิดไฟล์ อ่าน เขียน รวมถึงการรับและตั้งค่าแอตทริบิวต์ของไฟล์
1.1 เปิดและปิดไฟล์
ใน Go language คุณสามารถใช้ฟังก์ชัน os.Open
เพื่อเปิดไฟล์ ซึ่งจะส่งคืนออบเจ็กต์ *os.File
และข้อผิดพลาด หลังจากเปิดไฟล์แล้ว คุณสามารถดำเนินการอ่าน เขียน และดำเนินการอื่น ๆ หลังจากที่ดำเนินการเสร็จ คุณควรเรียก file.Close
เพื่อปิดไฟล์และปล่อยทรัพยากรที่เกี่ยวข้อง
นี่คือตัวอย่างการเปิดไฟล์:
package main
import (
"fmt"
"os"
)
func main() {
// เปิดไฟล์ test.txt ในไดเร็กทอรี่ปัจจุบัน
file, err := os.Open("test.txt")
if err != nil {
// จัดการข้อผิดพลาดในการเปิดไฟล์
fmt.Println("ข้อผิดพลาดในการเปิดไฟล์:", err)
return
}
// ใช้ defer statement เพื่อให้แน่ใจว่าไฟล์จะถูกปิดในที่สุด
defer file.Close()
// ดำเนินการกับไฟล์...
fmt.Println("เปิดไฟล์สำเร็จ")
}
ในโค้ดข้างต้น เราใช้ defer
statement เพื่อให้แน่ใจว่า file.Close
จะถูกประมาณ นี้เป็นการปฏิบัติที่พบใน Go language เพื่อทำความสะอาดทรัพยากร
1.2 การดำเนินการอ่านและเขียนไฟล์
ชนิดข้อมูล os.File
มีเมธอด Read
และ Write
ซึ่งสามารถใช้สำหรับการดำเนินการอ่านและเขียนไฟล์ เมธอด Read
อ่านข้อมูลจากไฟล์เข้าสู่ slice ของไบต์และเมธอด Write
ทำการเขียนข้อมูลจาก slice ของไบต์ไปยังไฟล์
ตัวอย่างต่อไปนี้แสดงให้เห็นว่า การอ่านและเขียนไปยังไฟล์:
package main
import (
"fmt"
"os"
)
func main() {
// เปิดไฟล์
file, err := os.OpenFile("test.txt", os.O_RDWR, 0644)
if err != nil {
fmt.Println("ข้อผิดพลาดในการเปิดไฟล์:", err)
return
}
defer file.Close()
// เขียนเนื้อหาไฟล์
message := []byte("สวัสดี นักพัฒนา!")
_, writeErr := file.Write(message)
if writeErr != nil {
fmt.Println("ข้อผิดพลาดในการเขียนไปยังไฟล์:", writeErr)
return
}
// อ่านไฟล์ตั้งแต่จุดเริ่มต้น
file.Seek(0, 0)
buffer := make([]byte, len(message))
_, readErr := file.Read(buffer)
if readErr != nil {
fmt.Println("ข้อผิดพลาดในการอ่านไฟล์:", readErr)
return
}
fmt.Println("เนื้อหาของไฟล์:", string(buffer))
}
ในตัวอย่างนี้ เราใช้ os.OpenFile
แทน os.Open
ซึ่งฟังก์ชัน os.OpenFile
ช่วยให้คุณระบุโหมดและสิทธิ์ที่จะใช้เมื่อเปิดไฟล์ ในตัวอย่างข้างต้น ใช้ธง os.O_RDWR
ซึ่งหมายความว่าไฟล์จะถูกเปิดในโหมดอ่าน-เขียน
1.3 คุณสมบัติและการอนุญาตของไฟล์
คุณสามารถใช้ฟังก์ชันจากแพ็คเกจ os
เพื่อเข้าถึงและปรับเปลี่ยนข้อมูลสถานะของไฟล์ ใช้ os.Stat
หรือ os.Lstat
เพื่อรับ os.FileInfo
interface ซึ่งให้ข้อมูลเกี่ยวกับไฟล์ เช่น ขนาด สิทธิ์การเข้าถึง วันเวลาการปรับเปลี่ยน และอื่น ๆ
นี่คือตัวอย่างการรับสถานะของไฟล์:
package main
import (
"fmt"
"os"
)
func main() {
fileInfo, err := os.Stat("test.txt")
if err != nil {
fmt.Println("เกิดข้อผิดพลาดในการรับข้อมูลของไฟล์:", err)
return
}
// พิมพ์ขนาดของไฟล์
fmt.Printf("ขนาดของไฟล์: %d ไบต์\n", fileInfo.Size())
// พิมพ์สิทธิ์การเข้าถึงของไฟล์
fmt.Printf("สิทธิ์การเข้าถึงของไฟล์: %s\n", fileInfo.Mode())
}
หากคุณต้องการเปลี่ยนชื่อของไฟล์หรือปรับเปลี่ยนสิทธิ์การเข้าถึงของไฟล์คุณสามารถใช้ os.Rename
เปลี่ยนชื่อของไฟล์ หรือ os.Chmod
เปลี่ยนสิทธิ์การเข้าถึงของไฟล์
package main
import (
"fmt"
"os"
)
func main() {
// เปลี่ยนสิทธิ์การเข้าถึงของไฟล์เป็นแบบอ่านอย่างเดียว
err := os.Chmod("test.txt", 0444)
if err != nil {
fmt.Println("เกิดข้อผิดพลาดในการเปลี่ยนสิทธิ์การเข้าถึงของไฟล์:", err)
return
}
// เปลี่ยนชื่อของไฟล์
renameErr := os.Rename("test.txt", "renamed.txt")
if renameErr != nil {
fmt.Println("เกิดข้อผิดพลาดในการเปลี่ยนชื่อของไฟล์:", renameErr)
return
}
fmt.Println("ดำเนินการกับไฟล์สำเร็จ")
}
ที่นี่ เราเปลี่ยนสิทธิ์การเข้าถึงของไฟล์ test.txt
เป็นแบบอ่านอย่างเดียว และจากนั้นเปลี่ยนชื่อไฟล์เป็น renamed.txt
โปรดทราบว่าเมื่อปรับเปลี่ยนสิทธิ์การเข้าถึงของไฟล์ ควรระมัดระวัง เนื่องจากการตั้งค่าสิทธิ์การเข้าถึงที่ไม่ถูกต้องอาจ导致ไฟล์ไม่สามารถเข้าถึงได้
2. การใช้งานพื้นฐานของไลบรารี IO
ในภาษา Go ไลบรารี io
ให้ส่วนของพื้นฐานสำหรับ I/O primitives (การดำเนินการนำเข้า/การดำเนินการส่งออก) การออกแบบของไลบรารี io
ทำตามหลักของความเรียบง่ายและการเชื่อมต่อที่สม่ำเสมอ ให้การสนับสนุนพื้นฐานสำหรับประเภทการดำเนินการ I/O ต่าง ๆ เช่น การอ่าน/เขียนไฟล์ การสื่อสารผ่านเครือข่าย การเตรียมข้อมูล และอื่น ๆ
2.2 การใช้งานอินเตอร์เฟซของการอ่านและเขียน
io.Reader
และ io.Writer
เป็นอินเตอร์เฟซพื้นฐานสองที่ใช้ระบุการดำเนินการอ่านและเขียนของวัตถุ พวกเขาถูกดำเนินการโดยประเภทต่าง ๆ เช่น ไฟล์ เชื่อมต่อเครือข่าย และบัฟเฟอร์
io.Reader
อินเตอร์เฟซ io.Reader
มีวิธีการ Read:
Read(p []byte) (n int, err error)
วิธีนี้อ่านข้อมูลได้สูงสุด len(p)
ไบต์ จาก io.Reader
เข้าสู่ p
มันจะคืนจำนวนไบต์ที่อ่านได้ n
(0 <= n
<= len(p
)) และข้อผิดพลาดใด ๆ
โค้ดตัวอย่าง:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("สวัสดี, โลก!")
buf := make([]byte, 4)
for {
n, err := r.Read(buf)
if err == io.EOF {
break
}
fmt.Printf("อ่านไบต์: %d, เนื้อหา: %s\n", n, buf[:n])
}
}
ในตัวอย่างนี้เราสร้าง strings.NewReader
เพื่ออ่านข้อมูลจากสตริง และจากนั้นอ่านข้อมูลเป็นชิ้นของ 4 ไบต์ทีละชิ้น
io.Writer
อินเตอร์เฟซ io.Writer
มีวิธีการ Write:
Write(p []byte) (n int, err error)
วิธีนี้เขียนข้อมูลจาก p
เข้าสู่สตรีมข้อมูลฐาน และคืนจำนวนไบต์ที่เขียนได้ประกอบกับข้อผิดพลาดใด ๆ
โค้ดตัวอย่าง:
package main
import (
"fmt"
"os"
)
func main() {
data := []byte("สวัสดี, โลก!\n")
n, err := os.Stdout.Write(data)
if err != nil {
panic(err)
}
fmt.Printf("ไบต์ที่เขียน: %d\n", n)
}
ตัวอย่างนี้เขียนสตริงง่ายไปที่เอาท์พุทมาตรฐาน os.Stdout
ซึ่งเป็นการดำเนินการแทน io.Writer
2.3 ฟังก์ชันการอ่าน/เขียนขั้นสูง
แพ็คเกจ io
มีฟังก์ชันบางอย่างที่สามารถช่วยให้งานทั่วๆ ไป เช่น การคัดลอกข้อมูลและการอ่านข้อมูลที่มีจำนวนที่กำหนด
ฟังก์ชันทำสำเนา
io.Copy
เป็นวิธีที่สะดวกสำหรับคัดลอกข้อมูลโดยตรงจาก io.Reader
ไปยัง io.Writer
โดยไม่ต้องใช้บัฟเฟอร์ชั่นอย่างชั่วคราว
โค้ดตัวอย่าง:
package main
import (
"io"
"os"
"strings"
)
func main() {
r := strings.NewReader("ตัวอย่างการคัดลอกข้อมูลอย่างง่าย")
_, err := io.Copy(os.Stdout, r)
if err != nil {
panic(err)
}
}
ในตัวอย่างนี้ เราได้ทำการคัดลอกข้อความไปที่ผลลัพธ์มาตรฐานโดยตรง
ฟังก์ชันการอ่านอย่างน้อย
ฟังก์ชัน io.ReadAtLeast
ใช้เพื่อให้แน่ใจว่าอย่างน้อยจำนวนที่กำหนดของข้อมูลถูกอ่านจาก io.Reader
ก่อนที่จะคืนค่า
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
โค้ดตัวอย่าง:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("เว็บไซต์ Go Language ภาษาจีน")
buf := make([]byte, 14)
n, err := io.ReadAtLeast(r, buf, 14)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s\n", buf[:n])
}
ในตัวอย่างนี้ io.ReadAtLeast
พยายามอ่านอย่างน้อย 14 ไบต์ข้อมูลเข้าไปใน buf
ฟังก์ชันการอ่าน/เขียนขั้นสูงเหล่านี้ช่วยให้คุณจัดการกับงานที่เกี่ยวข้องกับ I/O อย่างมีประสิทธิภาพมากขึ้น และให้พื้นฐานที่แข็งแกร่งสำหรับการสร้างตรรกะโปรแกรมที่ซับซ้อนมากขึ้น