Golang实现文件传输功能
作者:itzhuzhu. 时间:2023-08-05 13:50:31
本文实例为大家分享了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)
}
来源:https://blog.csdn.net/weixin_45477086/article/details/122933131
标签:Golang,文件传输
0
投稿
猜你喜欢
Vue mock.js模拟数据实现首页导航与左侧菜单功能
2024-05-09 09:51:57
“语法错误 (逗号) 在查询表达式id=20, 21”,怎么处理这个逗号?
2009-09-18 14:52:00
python字典setdefault方法和get方法使用实例
2023-11-23 21:13:15
python中使用矢量化替换循环详解
2023-08-27 00:51:01
PHP实现获取第一个中文首字母并进行排序的方法
2023-10-30 12:29:08
python发腾讯微博代码分享
2022-05-27 04:45:00
关于从MySQL转向ADODB的方法
2011-06-02 12:05:00
纯ASP结合VML生成完美图-饼图
2010-05-11 16:49:00
Python异步处理返回进度——使用Flask实现进度条
2023-10-19 23:23:08
Go系列教程之反射的用法
2024-04-25 15:25:32
python+opencv边缘提取与各函数参数解析
2023-12-24 11:17:54
pip已经安装好第三方库但pycharm中import时还是标红的解决方案
2022-05-25 00:50:16
深入理解Python虚拟机中字节(bytes)的实现原理及源码剖析
2021-12-20 22:51:28
利用Python实现绘制3D爱心的代码分享
2021-03-30 23:25:12
sql server不存在 sql server拒绝访问第1/3页
2024-01-22 02:18:41
PHP单例模式Singleton Pattern的原理与实现介绍
2023-05-26 13:33:28
MySQL 加密/压缩函数
2024-01-23 23:51:14
Pycharm远程连接服务器并运行与调试
2021-05-29 04:38:51
Python sklearn CountVectorizer使用详解
2023-06-20 08:19:05
SQLSERVER服务手工启动 批处理文件
2024-01-13 00:37:18