日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Golang實現文件傳輸功能_Golang

作者:itzhuzhu. ? 更新時間: 2022-09-18 編程語言

本文實例為大家分享了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

欄目分類
最近更新