Golang实现文件传输功能

作者:itzhuzhu. 时间:2023-08-05 13:50:31 

本文实例为大家分享了Golang实现文件传输的具体代码,供大家参考,具体内容如下

借助TCP完成文件的传输,基本思路如下:

1、发送方(客户端)向服务端发送文件名,服务端保存该文件名。
2、接收方(服务端)向客户端返回一个消息ok,确认文件名保存成功。
3、发送方(客户端)收到消息后,开始向服务端发送文件数据。
4、接收方(服务端)读取文件内容,写入到之前保存好的文件中。

Golang实现文件传输功能

首先获取文件名。借助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
  • asp之家 网络编程 m.aspxhome.com