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) }
执行结果: