Golang實(shí)現(xiàn)文件傳輸功能
本文實(shí)例為大家分享了Golang實(shí)現(xiàn)文件傳輸?shù)木唧w代碼,供大家參考,具體內(nèi)容如下
借助TCP完成文件的傳輸,基本思路如下:
1、發(fā)送方(客戶端)向服務(wù)端發(fā)送文件名,服務(wù)端保存該文件名。
2、接收方(服務(wù)端)向客戶端返回一個(gè)消息ok,確認(rèn)文件名保存成功。
3、發(fā)送方(客戶端)收到消息后,開(kāi)始向服務(wù)端發(fā)送文件數(shù)據(jù)。
4、接收方(服務(wù)端)讀取文件內(nèi)容,寫(xiě)入到之前保存好的文件中。

首先獲取文件名。借助os包中的stat()函數(shù)來(lái)獲取文件屬性信息。在函數(shù)返回的文件屬性中包含文件名和文件大小。Stat參數(shù)name傳入的是文件訪問(wèn)的絕對(duì)路徑。FileInfo中的Name()函數(shù)可以將文件名單獨(dú)提取出來(lái)。
func Stat(name string) (FileInfo, error)?
type FileInfo interface {
? ?Name() string ? ? ??
? ?Size() int64 ? ? ? ?
? ?Mode() FileMode ? ??
? ?ModTime() time.Time?
? ?IsDir() bool ? ? ? ?
? ?Sys() interface{} ??
}發(fā)送端:
package main
import (
?? ?"fmt"
?? ?"io"
?? ?"net"
?? ?"os"
)
func sendFile(conn net.Conn, filePath string) {
?? ?// 只讀打開(kāi)文件
?? ?f, err := os.Open(filePath)
?? ?if err != nil {
?? ??? ?fmt.Println("os.Open err:", err)
?? ??? ?return
?? ?}
?? ?defer f.Close()
?? ?// 從本文件中,讀數(shù)據(jù),寫(xiě)給網(wǎng)絡(luò)接收端。 讀多少,寫(xiě)多少。原封不動(dòng)。
?? ?buf := make([]byte, 1024)
?? ?for {
?? ??? ?n, err := f.Read(buf)
?? ??? ?if err != nil {
?? ??? ??? ?if err == io.EOF {
?? ??? ??? ??? ?fmt.Println("發(fā)送文件完成。")
?? ??? ??? ?} else {
?? ??? ??? ??? ?fmt.Println("os.Open err:", err)
?? ??? ??? ?}
?? ??? ??? ?return
?? ??? ?}
?? ??? ?// 寫(xiě)到網(wǎng)絡(luò)socket中
?? ??? ?_, err = conn.Write(buf[:n])
?? ??? ?if err != nil {
?? ??? ??? ?fmt.Println("conn.Write err:", err)
?? ??? ??? ?return
?? ??? ?}
?? ?}
}
func main() {
?? ?list := os.Args // 獲取命令行參數(shù)
?? ?if len(list) != 2 {
?? ??? ?fmt.Println("格式為:go run xxx.go 文件絕對(duì)路徑")
?? ??? ?return
?? ?}
?? ?// 提取 文件的絕對(duì)路徑
?? ?filePath := list[1]
?? ?//提取文件名
?? ?fileInfo, err := os.Stat(filePath)
?? ?if err != nil {
?? ??? ?fmt.Println("os.Stat err:", err)
?? ??? ?return
?? ?}
?? ?fileName := fileInfo.Name()
?? ?// 主動(dòng)發(fā)起連接請(qǐng)求
?? ?conn, err := net.Dial("tcp", "127.0.0.1:8000")
?? ?if err != nil {
?? ??? ?fmt.Println("net.Dial err:", err)
?? ??? ?return
?? ?}
?? ?defer conn.Close()
?? ?// 發(fā)送文件名給 接收端
?? ?_, err = conn.Write([]byte(fileName))
?? ?if err != nil {
?? ??? ?fmt.Println("conn.Write err:", err)
?? ??? ?return
?? ?}
?? ?// 讀取服務(wù)器回發(fā)的 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]) {
?? ??? ?// 寫(xiě)文件內(nèi)容給服務(wù)器——借助conn
?? ??? ?sendFile(conn, filePath)
?? ?}
}接收端:
package main
import (
?? ?"fmt"
?? ?"net"
?? ?"os"
)
func recvFile(conn net.Conn, fileName string) {
?? ?// 按照文件名創(chuàng)建新文件
?? ?f, err := os.Create(fileName)
?? ?if err != nil {
?? ??? ?fmt.Println("os.Create err:", err)
?? ??? ?return
?? ?}
?? ?defer f.Close()
?? ?// 從 網(wǎng)絡(luò)中讀數(shù)據(jù),寫(xiě)入本地文件
?? ?buf := make([]byte, 1024)
?? ?for {
?? ??? ?n, _ := conn.Read(buf)
?? ??? ?if n == 0 {
?? ??? ??? ?fmt.Println("接收文件完成。")
?? ??? ??? ?return
?? ??? ?}
?? ??? ?// 寫(xiě)入本地文件,讀多少,寫(xiě)多少。
?? ??? ?f.Write(buf[:n])
?? ?}
}
func main() {
?? ?// 創(chuàng)建用于監(jiān)聽(tīng)的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("接收端啟動(dòng)成功,等待發(fā)送端發(fā)送文件!")
?? ?// 阻塞監(jiān)聽(tīng)
?? ?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])
?? ?// 回寫(xiě) ok 給發(fā)送端
?? ?conn.Write([]byte("ok"))
?? ?// 獲取文件內(nèi)容
?? ?recvFile(conn, fileName)
}以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- GO語(yǔ)言原生實(shí)現(xiàn)文件上傳功能
- Go語(yǔ)言實(shí)現(xiàn)文件上傳
- GO實(shí)現(xiàn)文件上傳操作
- Go實(shí)現(xiàn)文件分片上傳
- Go Gin實(shí)現(xiàn)文件上傳下載的示例代碼
- golang實(shí)現(xiàn)ftp實(shí)時(shí)傳輸文件的案例
- Golang實(shí)現(xiàn)異步上傳文件支持進(jìn)度條查詢的方法
- golang socket斷點(diǎn)續(xù)傳大文件的實(shí)現(xiàn)方法
- 用go gin server來(lái)做文件上傳服務(wù)
- Golang+Android基于HttpURLConnection實(shí)現(xiàn)的文件上傳功能示例
相關(guān)文章
Golang實(shí)現(xiàn)簡(jiǎn)單http服務(wù)器的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Golang實(shí)現(xiàn)簡(jiǎn)單http服務(wù)器,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Golang有一定的幫助,需要的可以參考一下2023-03-03
Go處理JSON數(shù)據(jù)的實(shí)現(xiàn)
本文主要介紹了Go處理JSON數(shù)據(jù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
深入理解Go gin框架中Context的Request和Writer對(duì)象
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言的gin框架中Context的Request和Writer對(duì)象,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Go語(yǔ)言有一定的幫助,快跟隨小編一起學(xué)習(xí)一下吧2023-04-04
Go實(shí)現(xiàn)生產(chǎn)隨機(jī)密碼的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Go實(shí)現(xiàn)生產(chǎn)隨機(jī)密碼的,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下2023-09-09
基于Go語(yǔ)言實(shí)現(xiàn)高性能文件上傳下載系統(tǒng)
在Web應(yīng)用開(kāi)發(fā)中,文件上傳下載是一個(gè)非常常見(jiàn)的需求,本文將介紹如何使用Go語(yǔ)言實(shí)現(xiàn)一個(gè)安全、高效的本地文件存儲(chǔ)系統(tǒng),感興趣的小伙伴可以了解下2025-03-03

