共计 2432 个字符,预计需要花费 7 分钟才能阅读完成。
导读 | 这篇文章主要为大家详细介绍了 Golang 实现文件传输功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 |
本文实例为大家分享了 Golang 实现文件传输的具体代码,供大家参考,具体内容如下
借助 TCP 完成文件的传输,基本思路如下:
1、发送方(客户端)向服务端发送文件名,服务端保存该文件名。
2、接收方(服务端)向客户端返回一个消息 ok,确认文件名保存成功。
3、发送方(客户端)收到消息后,开始向服务端发送文件数据。
4、接收方(服务端)读取文件内容,写入到之前保存好的文件中。
首先获取文件名。借助 os 包中的 stat() 函数来获取文件属性信息。在函数返回的文件属性中包含文件名和文件大小。Stat 参数 name 传入的是文件访问的绝对路径。FileInfo 中的 Name() 函数可以将文件名单独提取出来。
func Stat(name string) (FileInfo, error)
type FileInfo interface {Name() string
Size() int64
Mode() FileMode
ModTime() time.Time
IsDir() bool
Sys() interface{}
}
发送端:
package main
import (
"fmt"
"io"
"net"
"os"
)
func sendFile(conn net.Conn, filePath string) {
// 只读打开文件
f, err := os.Open(filePath)
if err != nil {fmt.Println("os.Open err:", err)
return
}
defer f.Close()
// 从本文件中,读数据,写给网络接收端。读多少,写多少。原封不动。buf := make([]byte, 1024)
for {n, err := f.Read(buf)
if err != nil {
if err == io.EOF {fmt.Println("发送文件完成。")
} else {fmt.Println("os.Open err:", err)
}
return
}
// 写到网络 socket 中
_, err = conn.Write(buf[:n])
if err != nil {fmt.Println("conn.Write err:", err)
return
}
}
}
func main() {
list := os.Args // 获取命令行参数
if len(list) != 2 {fmt.Println("格式为:go run xxx.go 文件绝对路径")
return
}
// 提取 文件的绝对路径
filePath := list[1]
// 提取文件名
fileInfo, err := os.Stat(filePath)
if err != nil {fmt.Println("os.Stat err:", err)
return
}
fileName := fileInfo.Name()
// 主动发起连接请求
conn, err := net.Dial("tcp", "127.0.0.1:8000")
if err != nil {fmt.Println("net.Dial err:", err)
return
}
defer conn.Close()
// 发送文件名给 接收端
_, err = conn.Write([]byte(fileName))
if err != nil {fmt.Println("conn.Write err:", err)
return
}
// 读取服务器回发的 OK
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {fmt.Println("conn.Read err:", err)
return
}
if "ok" == string(buf[:n]) {
// 写文件内容给服务器——借助 conn
sendFile(conn, filePath)
}
}
接收端:
package main
import (
"fmt"
"net"
"os"
)
func recvFile(conn net.Conn, fileName string) {
// 按照文件名创建新文件
f, err := os.Create(fileName)
if err != nil {fmt.Println("os.Create err:", err)
return
}
defer f.Close()
// 从 网络中读数据,写入本地文件
buf := make([]byte, 1024)
for {n, _ := conn.Read(buf)
if n == 0 {fmt.Println("接收文件完成。")
return
}
// 写入本地文件,读多少,写多少。f.Write(buf[:n])
}
}
func main() {
// 创建用于监听的 socket
listener, err := net.Listen("tcp", "127.0.0.1:8000")
if err != nil {fmt.Println("net.Listen err:", err)
return
}
defer listener.Close()
fmt.Println("接收端启动成功,等待发送端发送文件!")
// 阻塞监听
conn, err := listener.Accept()
if err != nil {fmt.Println("listener.Accept() err:", err)
return
}
defer conn.Close()
// 获取文件名,保存
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {fmt.Println("conn.Read err:", err)
return
}
fileName := string(buf[:n])
// 回写 ok 给发送端
conn.Write([]byte("ok"))
// 获取文件内容
recvFile(conn, fileName)
}
以上就是本文的全部内容,希望对大家的学习有所帮助
正文完
星哥说事-微信公众号
![post-qrcode](https://www.xgss.net/wp-content/uploads/2023/07/二维码-微信公众号256x256.jpg)