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ā)送方(客戶端)收到消息后,開始向服務(wù)端發(fā)送文件數(shù)據(jù)。
4、接收方(服務(wù)端)讀取文件內(nèi)容,寫入到之前保存好的文件中。

首先獲取文件名。借助os包中的stat()函數(shù)來獲取文件屬性信息。在函數(shù)返回的文件屬性中包含文件名和文件大小。Stat參數(shù)name傳入的是文件訪問的絕對(duì)路徑。FileInfo中的Name()函數(shù)可以將文件名單獨(dú)提取出來。
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) {
?? ?// 只讀打開文件
?? ?f, err := os.Open(filePath)
?? ?if err != nil {
?? ??? ?fmt.Println("os.Open err:", err)
?? ??? ?return
?? ?}
?? ?defer f.Close()
?? ?// 從本文件中,讀數(shù)據(jù),寫給網(wǎng)絡(luò)接收端。 讀多少,寫多少。原封不動(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
?? ??? ?}
?? ??? ?// 寫到網(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]) {
?? ??? ?// 寫文件內(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ù),寫入本地文件
?? ?buf := make([]byte, 1024)
?? ?for {
?? ??? ?n, _ := conn.Read(buf)
?? ??? ?if n == 0 {
?? ??? ??? ?fmt.Println("接收文件完成。")
?? ??? ??? ?return
?? ??? ?}
?? ??? ?// 寫入本地文件,讀多少,寫多少。
?? ??? ?f.Write(buf[:n])
?? ?}
}
func main() {
?? ?// 創(chuàng)建用于監(jiān)聽的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)聽
?? ?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 給發(fā)送端
?? ?conn.Write([]byte("ok"))
?? ?// 獲取文件內(nèi)容
?? ?recvFile(conn, fileName)
}以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- GO語言原生實(shí)現(xiàn)文件上傳功能
- Go語言實(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來做文件上傳服務(wù)
- Golang+Android基于HttpURLConnection實(shí)現(xiàn)的文件上傳功能示例
相關(guān)文章
基于Go語言實(shí)現(xiàn)應(yīng)用IP防火墻
在公司里面經(jīng)常會(huì)聽到某應(yīng)用有安全漏洞問題,沒有做安全加固,IP防火墻就是一個(gè)典型的安全加固解決方案,下面我們就來學(xué)習(xí)一下如何使用go語言實(shí)現(xiàn)IP防火墻吧2023-11-11
golang對(duì)自定義類型進(jìn)行排序的解決方法
學(xué)習(xí)一門編程語言,要掌握原子數(shù)據(jù)類型,還需要掌握自定義數(shù)據(jù)類型。下面這篇文章主要給大家介紹了關(guān)于golang如何對(duì)自定義類型進(jìn)行排序的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-12-12
Go語言開發(fā)kube-scheduler整體架構(gòu)深度剖析
這篇文章主要為大家介紹了Go語言開發(fā)kube-scheduler整體架構(gòu)深度剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
關(guān)于go語言載入json可能遇到的一個(gè)坑
Go 語言從新手到大神,每個(gè)人多少都會(huì)踩一些坑,那么下面這篇文章主要給大家介紹了關(guān)于go語言載入json可能遇到的一個(gè)坑,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-07-07
Go Gin框架中的路由組及其優(yōu)先級(jí)探索分析
在構(gòu)建Web應(yīng)用程序時(shí),理解和有效地使用路由是至關(guān)重要的,Go語言的Gin框架為此提供了強(qiáng)大的工具,特別是通過其路由組功能,本文將深入探討Gin的RouterGroup,特別是在路徑匹配和優(yōu)先級(jí)方面的行為2024-01-01
Linux系統(tǒng)下Go語言開發(fā)環(huán)境搭建
這篇文章主要介紹了Linux系統(tǒng)下Go開發(fā)環(huán)境搭建,需要的朋友可以參考下2022-04-04
分布式架構(gòu)在Go語言網(wǎng)站的應(yīng)用
分布式架構(gòu)是目前應(yīng)對(duì)高流量、高并發(fā)的重要解決方案,分布式架構(gòu)的核心思想是分而治之,將單臺(tái)服務(wù)器的資源劃分為多臺(tái)服務(wù)器進(jìn)行協(xié)同完成,分布式架構(gòu)應(yīng)用于Go語言網(wǎng)站中既能提升服務(wù)速度,又能降低了服務(wù)器宕機(jī)的風(fēng)險(xiǎn)2024-01-01

