[ go 与 golang | 青训营笔记]
这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天, 在学习了go的相关基础知识以后,可以说是初步的了解了go,我在这过程中也记录了一些自己的学习经验以及心得,与大家分享一下。
25. IO
Seek interface
type Seeker interface {
Seek(offset int64, whence int) (int64, error)
}
offset是指针移动的偏移量
whence表示指针移动的方式
0 从数据的头部开始移动指针
1 从数据的当前指针位置开始移动指针
2 从数据的尾部移动指针
seek设置下一次读写操作的指针位置,每次的读写操作都是从指针位置开始的
Close interface
type Closer interface {
Close() error
}
关闭文件
文件打开模块
O_RDONLY int = syscall.O_RDONLY // 只读
O_WRONLY int = syscall.O_WRONLY // 只写
O_RDWR int = syscall.O_RDWR // 读写
O_APPEND int = syscall.O_APPEND // 追加
O_CREATE int = syscall.O_CREAT // 如果不存在就创建
O_EXCL int = syscall.O_EXCL // 文件必须不存在
O_SYNC int = syscall.O_SYNC // 同步io
O_TRUNC int = syscall.O_TRUNC // 打开时清空文件
读取文件
os.Open(name string) (file *File, err error)
ioutil.ReadFile(name string) ([]byte, error)
os.ReadFile(name string) ([]byte, error)
os.OpenFile(name string, flag int, perm FileMode) (*File, error)
一次性读
func main() {
bs, err := os.ReadFile("./abc.txt")
if err != nil {
fmt.Printf("Read file error: %v\n", err)
return
}
fmt.Printf("%s\n", bs)
}
分片读
func main() {
file, err := os.Open("abc.txt")
if err != nil {
panic(err)
}
defer file.Close()
for {
buf := make([]byte, 32)
_, err = file.Read(buf)
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
fmt.Printf("%s", buf)
}
}
带缓冲读
func main() {
file, err := os.Open("./abc.txt")
if err != nil {
fmt.Printf("Open file error: %v\n", err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
// 按行读取
line, err := reader.ReadString('\n')
if err == io.EOF {
break
}
fmt.Print(line)
}
}
光标操作
file, _ := os.Open("abc.txt")
defer file.Close()
// 开始位置前进5个字节
var whence = 0
var offset int64 = 5
pos, _ := file.Seek(offset, whence)
fmt.Println("Jump forward 5 bytes from start position:", pos)
// 当前位置回退2个字节
whence = 1
offset = -2
pos, _ = file.Seek(offset, whence)
fmt.Println("Jump back 2 bytes from current position:", pos)
}
分隔符读
func main() {
file, _ := os.Open("abc.txt")
defer file.Close()
scanner := bufio.NewScanner(file)
// 分隔函数,默认 bufio.ScanLines
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
err := scanner.Err()
if err != nil {
panic(err)
}
}
按行读
func main() {
file, _ := os.Open("abc.txt")
defer file.Close()
scanner := bufio.NewScanner(file)
// 分隔函数,默认 bufio.ScanLines
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
err := scanner.Err()
if err != nil {
panic(err)
}
}
写入文件
os.OpenFile(name string, flag int, perm FileMode) (file *File, err error)
os.Create(name string) (*File, error)
io/ioutil.Write(filename string, data []byte, perm fs.FileMode) error
文件操作模式:
覆盖写:os.O_WRONLY | os.O_TRUNC
追加写:os.O_WRONLY | os.O_APPEND
读写并追加:os.O_RDWR | os.OS_APPENDCopyErrorOK!
常规写
func writeFile() {
file, err := os.OpenFile("abc.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644)
if err != nil {
panic(err)
}
defer file.Close()
byteSlice := []byte("hello world!")
bytesWritten, err := file.Write(byteSlice)
if err != nil {
panic(err)
}
fmt.Printf("Wrote %d bytes\n", bytesWritten)
}
快速写
func main() {
err := ioutil.WriteFile("abc.txt", []byte("add a new line"), 0644)
if err != nil {
panic(err)
}
}
缓冲写
func main() {
file, err := os.OpenFile("abc.txt", os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
panic(err)
}
defer file.Close()
msg := "Hello World!\n"
writer := bufio.NewWriter(file)
for i := 0; i < 5; i++ {
writer.Write([]byte(msg))
}
writer.Flush()
}
复制文件
io.Copy(dst Writer, src Reader) (written int64, err error)CopyErrorOK!
read, _ := os.Open("xxx.jpg")
write, _ := os.Create("xx2.jpg")
n, err := io.Copy(write, read)
fmt.Println(n, err)CopyErrorOK!
目录操作
递归展示文件夹下所有文件
func readDir(path string) {
dir, err := os.ReadDir(path)
if err != nil {
fmt.Println(err)
return
}
for _, entry := range dir {
name := entry.Name()
nPath := fmt.Sprintf("%s/%s", path, name)
if entry.IsDir() {
readDir(nPath)
continue
}
fmt.Println(nPath)
}
}
26. 网络编程
TCP
服务端
package main
import (
"fmt"
"io"
"net"
)
func main() {
// 创建tcp的监听地址
tcpAddr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
// tcp监听
listen, _ := net.ListenTCP("tcp", tcpAddr)
for {
// 等待连接
conn, err := listen.AcceptTCP()
if err != nil {
fmt.Println(err)
break
}
// 获取客户端的地址
fmt.Println(conn.RemoteAddr().String() + " 进来了")
// 读取客户端传来的数据
for {
var buf []byte = make([]byte, 1024)
n, err := conn.Read(buf)
// 客户端退出
if err == io.EOF {
fmt.Println(conn.RemoteAddr().String() + " 出去了")
break
}
fmt.Println(string(buf[0:n]))
}
}
}
客户端
package main
import (
"fmt"
"net"
)
func main() {
conn, _ := net.DialTCP("tcp", nil,
&net.TCPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: 8080})
var s string
for {
fmt.Scanln(&s)
if s == "q" {
break
}
conn.Write([]byte(s))
}
conn.Close()
}