• Go语言之进阶篇文件传输


     一、文件传输

    1、文件传输原理

    2、文件传输

    示例:

    发送方: send_file.go

    package main
    
    import (
    	"fmt"
    	"io"
    	"net"
    	"os"
    )
    
    //发送文件内容
    func SendFile(path string, conn net.Conn) {
    	//以只读方式打开文件
    	f, err := os.Open(path)
    	if err != nil {
    		fmt.Println("os.Open err = ", err)
    		return
    	}
    
    	defer f.Close()
    
    	buf := make([]byte, 1024*4)
    
    	//读文件内容,读多少发多少,一点不差
    	for {
    		n, err := f.Read(buf) //从文件读取内容
    		if err != nil {
    			if err == io.EOF {
    				fmt.Println("文件发送完毕")
    			} else {
    				fmt.Println("f.Read err = ", err)
    			}
    
    			return
    		}
    
    		//发送内容
    		conn.Write(buf[:n]) //给服务器发送内容
    	}
    
    }
    
    func main() {
    	//提示输入文件
    	fmt.Println("请输入需要传输的文件:")
    	var path string
    	fmt.Scan(&path)
    
    	//获取文件名 info.Name()
    	info, err := os.Stat(path)
    	if err != nil {
    		fmt.Println("os.Stat err = ", err)
    		return
    	}
    
    	//主动连接服务器
    	conn, err1 := net.Dial("tcp", "127.0.0.1:8000")
    	if err1 != nil {
    		fmt.Println("net.Dial err1 = ", err1)
    		return
    	}
    
    	defer conn.Close()
    
    	//给接收方,先发送文件名
    	_, err = conn.Write([]byte(info.Name()))
    	if err != nil {
    		fmt.Println("conn.Write err = ", err)
    		return
    	}
    
    	//接收对方的回复,如果回复"ok", 说明对方准备好,可以发文件
    	var n int
    	buf := make([]byte, 1024)
    
    	n, err = conn.Read(buf)
    	if err != nil {
    		fmt.Println("conn.Read err = ", err)
    		return
    	}
    
    	if "ok" == string(buf[:n]) {
    		//发送文件内容
    		SendFile(path, conn)
    	}
    }
    

    接收方: recv_file.go

    package main
    
    import (
    	"fmt"
    	"io"
    	"net"
    	"os"
    )
    
    //接收文件内容
    func RecvFile(fileName string, conn net.Conn) {
    	//新建文件
    	f, err := os.Create(fileName)
    	if err != nil {
    		fmt.Println("os.Create err = ", err)
    		return
    	}
    
    	buf := make([]byte, 1024*4)
    
    	//接收多少,写多少,一点不差
    	for {
    		n, err := conn.Read(buf) //接收对方发过来的文件内容
    		if err != nil {
    			if err == io.EOF {
    				fmt.Println("文件接收完毕")
    			} else {
    				fmt.Println("conn.Read err = ", err)
    			}
    			return
    		}
    
    		if n == 0 {
    			fmt.Println("n == 0 文件接收完毕")
    			break
    		}
    
    		f.Write(buf[:n]) //往文件写入内容
    	}
    
    }
    
    func main() {
    	//监听
    	listenner, err := net.Listen("tcp", "127.0.0.1:8000")
    	if err != nil {
    		fmt.Println("net.Listen err = ", err)
    		return
    	}
    
    	defer listenner.Close()
    
    	//阻塞等待用户连接
    	conn, err1 := listenner.Accept()
    	if err1 != nil {
    		fmt.Println("listenner.Accept err = ", err1)
    		return
    	}
    
    	defer conn.Close()
    
    	buf := make([]byte, 1024)
    	var n int
    	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(fileName, conn)
    
    }
    

    执行结果:

  • 相关阅读:
    借助backtrace和demangle实现异常类Exception
    mysql数据库表里首行和末行的取得方法
    斐波那契高效算法(4种算法综合分析)
    sublime学习之--批量在多行首位加入代码
    Zabbix --> client安装以及怎样加入数据库的动态监控视图
    sdut 3-6 静态数据成员与静态成员函数
    poj3411Paid Roads
    python中get pass用法
    Qt之QListWidget:项目的多选与单选设置
    Qt之QListWidget:项目的多选与单选设置
  • 原文地址:https://www.cnblogs.com/nulige/p/10302849.html
Copyright © 2020-2023  润新知