当前位置: 首页 > article >正文

Go IO之文件处理,TCPUDP讲解

文章目录

  • 1 文件处理
    • 1.1 打开和关闭文件
    • 1.2 读取文件
      • 1.2.1 简单示例
      • 1.2.2 中文乱码
        • 1.2.2.1 bufio
        • 1.2.2.2 ioutil
    • 1.3 写入文件
      • 1.3.1 Write 和 WriteString
      • 1.3.2 fmt.Fprintln
        • 1.3.2.1 写入文件
        • 1.3.2.2 写入标准输出
      • 1.3.3 bufio.NewWriter
      • 1.3.4 ioutil.WriteFile
  • 2 TCP&UDP
    • 2.1 TCP
      • 2.1.1 服务端
      • 2.1.2 客户端配置
    • 2.2 UDP
      • 2.2.1 服务端配置
      • 2.2.2 客户端配置

1 文件处理

1.1 打开和关闭文件

os.open() 函数能够打开一个文件,返回一个 *File 和一个 err,对得到的文件使用 close() 方法能够关闭文件。

package main

import (
    "fmt"
    "os"
)

// 打开关闭文件
func main() {        
    // 打开当前目录下的 abc.txt 文件
    file,err := os.Open("./abc.txt")
    if err != nil {        
        fmt.Println("文件打开失败",err)
    } else {     
        fmt.Println("文件打开成功")
        file.Close()	// 从内存释放资源
        fmt.Println("文件关闭成功")
    }
}
/*
文件打开成功
文件关闭成功
*/

1.2 读取文件

接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回 0io.EOF

func (f *File) Read(b []byte) (n int, err error)

1.2.1 简单示例

package main

import (
    "fmt"
    "io"
    "os"
)

// 打开关闭文件
func main() {        
    // 打开当前目录下的 abc.txt 文件
    file,err := os.Open("./abc.txt")
    if err != nil {        
        fmt.Println("文件打开失败",err)
        return
    }
    // 文件能打开
    defer file.Close()	// 使用 defer 延迟开关,main 函数即将结束前释放文件资源
    fmt.Println("文件成功打开")
    // 读文件
    var tmp [128]byte	// 定义一个字节切片,每次读 128 字节
    n,err := file.Read(tmp[:])
    // 文件读完
    if err == io.EOF {        
        fmt.Println("文件已读完")
        return
    }
    // 读取中报错
    if err != nil {        
        fmt.Println("Read from file failed,err",err)
        return
    }
    fmt.Printf("读取 %d 个字节\n",n)
    fmt.Println(string(tmp[:]))
    // fmt.Printf("获取的内容是:%s\n",string(tmp[:]))
}

/*
读取 23 个字节
adadadsad
sdsadasdas
*/

循环读取文件

package main

import (
    "fmt"
    "io"
    "os"
)

// 打开关闭文件
func main() {        
    // 打开当前目录下的 abc.txt 文件
    file,err := os.Open("./abc.txt")
    if err != nil {        
        fmt.Println("文件打开失败",err)
        return
    }
    // 文件能打开
    defer file.Close()	// 使用 defer 延迟开关,main 函数即将结束前释放文件资源
    fmt.Println("文件成功打开")
    // 读文件
    var tmp [128]byte	// 定义一个字节切片,每次读 128 字节
    // for 循环读取内容,输出到程序中
    for {        
        _,err := file.Read(tmp[:])
        // 文件读完
        if err == io.EOF {   
            fmt.Println("文件已读完",err)
            return
        }
        // 读取中报错
        if err != nil {        
            fmt.Println("Read from file failed,err",err)
            return
        }
        fmt.Printf("%s",string(tmp[:]))
    }
}

1.2.2 中文乱码

1.2.2.1 bufio

如果有乱码,可以使用 bufio 读取。bufiofile 的基础上封装了一层 API,支持更多的功能。

package main
import (
    "fmt"
    "os"
    "io"
    "bufio"
)

// bufio 读数据
func main() {        
    file,err := os.Open("./abc.txt")
    if err != nil {        
        fmt.Println("文件打开失败",err)
        return
    }
    defer file.Close()
    // 封装一个 API 层
    // 利用缓冲区从文件读数据
    reader := bufio.NewReader(file)
    for {        
        str,err := reader.ReadString('\n')	// 字符
        if err == io.EOF {        
            fmt.Print(str)	// 要输出,否则不显示
            return
        }
        if err != nil {   
            fmt.Println("读取文件内容失败",err)
            return
        }
        fmt.Print(str)	// 取消文件中的自带换行
    }
}

示例:读取奇/偶数行

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

// bufio 读数据
func main() {        
	file, err := os.Open("./abc.txt")
	if err != nil {   
		fmt.Println("文件打开失败", err)
		return
	}
	defer file.Close()
	// 利用缓冲区从文件读数据
	reader := bufio.NewReader(file)
	count := 0
	for {   
		// 输出奇数行
		str, _, err := reader.ReadLine()
		count++
		if err == io.EOF {        
			return
		}
		if err != nil {        
			fmt.Println("读取文件内容失败", err)
			return
		}
		if count%2 == 1 {   
     	// 0 为偶数
			fmt.Println(string(str))
		}
	}
}
1.2.2.2 ioutil
package main

import (
    "fmt"
    "io/ioutil"
)
// ioutil 读取文件
func readFile(filename string) {        
    content,err := ioutil.ReadFile(filename)
    if err != nil {   
        fmt.Println("READ FILE FAILED,ERR:",err)
        return
    }
    fmt.Println(string(content))
}
func main() {       
    readFile("./abc.txt")
}

1.3 写入文件

os.OpenFile() 函数能够以指定模式打开文件,从而实现文件写入相关功能。

func OpenFile(name string, flag int, perm FileMode)(*File,error) {     
    ...
}

说明:

  • name:要打开的文件名
  • flag:打开文件的模式
    模式种类:
    • os.O_WRONLY:只写
    • os.O_CREATE:创建文件
    • os.O_RDONLY:只读
    • vos.O_RDWR:读写
    • os.O_TRUNC:清空
    • os.O_APPEND:追加
  • perm:文件权限,一个八进制数。r(读)04,w(写)02,x(执行)01。

1.3.1 Write 和 WriteString

package main

import (
    "fmt"
    "os"
)
// 打开文件支持文件写入
func main() {        
    // 创建 tmp.txt 文件,分配权限 755
    file,err := os.OpenFile("tmp.txt",os.O_CREATE|os.O_WRONLY,0755)
    if err != nil {        
        fmt.Println("打开文件失败",err)
        return
    }
    defer file.Close()
    // 定义写入内容
    str := "hello world"
    // 字节方式写入
    file.Write([]byte("this is test\n"))
    // 字符串方式写入
    defer file.WriteString(str)
}

/* tmp.txt
this is test
hello world
*/

1.3.2 fmt.Fprintln

1.3.2.1 写入文件

fmt.Fprintln(f, v) 是 把 v 的内容写入到 f 中。
解释:

  • f 是一个 io.Writer 类型的对象,表示你要写入数据的目标。常见的目标包括文件、标准输出(os.Stdout)、缓冲区等。
  • v 是希望写入到 f 中的数据,v 可以是任何可以格式化的类型,例如 string、int、struct 等。

fmt.Fprintln(f, v) 的作用是将 v 的值写入 f 中,并且在写入的值后面会自动添加换行符 \n

package main

import (
    "fmt"
    "os"
)

func main() {
    // 创建或打开文件
    f, err := os.Create("output.txt")
    if err != nil {
        fmt.Println("Error creating file:", err)
        return
    }
    defer f.Close()

    // 要写入文件的内容
    v := "Hello, world!"
    fmt.Fprintln(f, v)  // 将 v 写入文件 f
}
1.3.2.2 写入标准输出

如果想把某个值写到控制台

fmt.Fprintln(os.Stdout, "Hello, Go!")

这个代码会将字符串 “Hello, Go!” 输出到标准输出(即控制台)

1.3.3 bufio.NewWriter

package main

import (
    "fmt"
    "os"
    "bufio"
)
// 打开文件支持文件写入
func main() {        
    file,err := os.OpenFile("tmp.txt",os.O_CREATE|os.O_WRONLY|os.O_TRUNC,0666)
    if err != nil {        
        fmt.Println("打开文件失败",err)
        return
    }
    defer file.Close()
    // 定义写入内容
    write := bufio.NewWriter(file)
    defer write.Flush() // 确保缓冲区数据被写入
    for i:=0;i<10;i++ {        
        write.WriteString("hello world\n")	// 将数据写入缓存
    }
}    

/* tmp.txt
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
*/

1.3.4 ioutil.WriteFile

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {        
    str := "hello world\nthis is test"
    // 字符串转换为字节数组写入
    err := ioutil.WriteFile("./tmp.txt",[]byte(str),0666)
    if err != nil {        
        fmt.Println("文件写入错误",err)
        return
    }
}

/* tmp.txt
hello world
this is test
*/

2 TCP&UDP

2.1 TCP

2.1.1 服务端

一个服务端连接多个客户端,例如:世界各地的用户使用自己电脑的浏览器访问淘宝网。

package main

import (
	"fmt"
	"net"
)
/* TCP 服务端 */
// 处理客户端连接函数
func process(conn net.Conn) {       
	defer conn.Close()
	var buf [1024]byte
	n,err := conn.Read(buf[:])	// 读取切片数据
	if err != nil {   
		fmt.Println("read err:",err)
		return
	}
	str := string(buf[:n])	// 转换字符串
	fmt.Println("收到客户端发来的数据:",str)
}

func main() {        
	// 1. 监听端口
	listener,err := net.Listen("tcp","127.0.0.1:20000")
	// 连接失败处理
	if err != nil {        
		fmt.Println("启动服务失败,err:",err)
		return
	}
	// 程序退出时释放端口
	defer listener.Close()    
	for {        
		// 2. 建立连接
		// conn 是返回的接口
		conn,err := listener.Accept()
		if err != nil {        
			fmt.Println("接收客户端连接失败,err",err)
			continue	// 继续阻塞,等待客户端再次连接
		}
		// 3. 启动一个 goroutine 处理客户端连接
		go process(conn)
	}
}

2.1.2 客户端配置

package main

import (
	"fmt"
	"net"
)

/* TCP 客户端配置 */
func main() {        
	// 1. 拨号方式建立与服务端连接
	conn,err := net.Dial("tcp","127.0.0.1:20000")
	if err != nil {        
		fmt.Println("连接服务端失败,err:",err)
		return
	}
	// 注意:关闭连接位置,不能写在连接失败判断上面
	defer conn.Close()
	// 2. 向 server 发送信息
	// fmt.Fprintln(conn,"hello")
	_,err = conn.Write([]byte("hello,tom"))
	if err != nil {        
		fmt.Println("发送消息失败,err:",err)
		return
	}
}

2.2 UDP

UDP是用户数据报协议,是一种无连接传输协议,不需要建立连接就可以直接发送和接收数据,属于不可靠的,没有时序的通信,UDP 实时性好,适合直播环境。

2.2.1 服务端配置

package main

import (
    "fmt"
    "net"
)

/* UDP 服务端 */
func main() {   
    // 1. 监听
    listener,err := net.ListenUDP("udp",&net.UDPAddr {        
        IP:		net.ParseIP("127.0.0.1"),
        Port:	30000,
    })
    if err != nil {        
        fmt.Println("启动 server 失败,err:",err)
        return
    }
    // 退出时关闭资源
    defer listener.Close()
    // 循环收发数据
    for {        
        var buf [1024]byte
        // 因为是无连接,所以需要知道对方地址 Addr
        n,addr,err := listener.ReadFromUDP(buf[:])
        if err != nil {        
            fmt.Println("接收消息失败,err:",err)
            return
        }
        fmt.Printf("接收到来自 %v 的消息:%v\n",addr,string(buf[:n]))
        // 回复消息
        n,err = listener.WriteToUDP([]byte("hi"),addr)
        if err != nil {       
            fmt.Println("回复失败,err:",err)
            return
        }
    }
}

2.2.2 客户端配置

package main

import (
	"fmt"
	"net"
)

/* UDP 客户端 */
func main() {   
	// 连接 UDP 服务器
	conn,err := net.Dial("udp","127.0.0.1:30000")
	if err != nil {        
		fmt.Println("连接失败,err:",err)
		return
	}
	defer conn.Close()
	// 发送消息
	n,err := conn.Write([]byte("hello"))
	if err != nil {        
		fmt.Println("发送失败,err:",err)
		return
	}
	// 接收消息
	var buf [1024]byte
	n,err = conn.Read(buf[:])	// n 为返回的有效字节个数
	if err != nil {        
		fmt.Println("接收消息失败,err:",err)
		return
	}
	fmt.Println("收到回复:",string(buf[:n]))
}

http://www.kler.cn/a/458437.html

相关文章:

  • TypeScript 后端开发中的热重载编译处理
  • 【QGIS入门实战精品教程】7.3:QGIS制作千层饼(DEM+等高线+影像+TIN)
  • 深度学习论文: RemDet: Rethinking Efficient Model Design for UAV Object Detection
  • Kafka 幂等性与事务
  • 前端不显示验证码图片
  • 汽车损坏识别检测数据集,使用yolo,pasical voc xml,coco json格式标注,6696张图片,可识别11种损坏类型,识别率89.7%
  • CF2043b-B. Digits
  • ASP.NET Core Web API Hangfire
  • C# OpenCV机器视觉:漫水填充
  • 春招快速准备和是否考研建议
  • 深度学习实战102-基于深度学习的网络入侵检测系统,利用各种AI模型和pytorch框架实现网络入侵检测
  • STM32高级 以太网通讯案例1:网络搭建(register代码)
  • leetcode 面试经典 150 题:删除有序数组中的重复项
  • 基于SSM的“一汽租车辆共享平台”的设计与实现(源码+数据库+文档+PPT)
  • vue-复制剪贴板
  • pytorch整体环境打包安装到另一台电脑上
  • 高级技巧-使用Mysql 实现根据条件过滤整个分组数据
  • 正则化强度的倒数C——让模型学习更准确
  • Bash 脚本教程
  • 【Python】什么是元组(Tuple)?
  • TCP/IP原理
  • OpenCV-Python实战(4)——图像处理基础知识
  • 数据资产运营平台如何搭建?数据要素资产运营平台解决方案 解读
  • C++软件设计模式之代理(Proxy)模式
  • pikachu靶场搭建详细步骤
  • 爬虫入门一 基础知识 以及request