楔子
學習 314_尚硅谷_Go核心編程_海量用戶通訊系統 在其基礎上實現 登錄後文件傳輸到服務器。
遇到了問題,自定義了報文格式,如何實現文件傳輸。使用 網絡傳輸Byte數組最簡單的就是用base64對byte數組進行編碼,進過編碼後得到String傳輸到對端解碼得出byte數組
go base64編解碼
package main
import (
"encoding/base64"
"fmt"
)
func main() {
base64encode()
}
func base64encode() {
bytes := []byte("hello 編解碼")
encodeToString := base64.StdEncoding.EncodeToString(bytes)
fmt.Println(bytes, "編碼後的內容爲", encodeToString)
fmt.Println("解碼")
decodeString, err := base64.StdEncoding.DecodeString(encodeToString)
fmt.Println(decodeString, "|", err)
}
文件傳輸
客戶端發送
package process
import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
"study/qq/client/utils"
"study/qq/common/message"
)
/********************************************
|客戶端發送數據到服務器
*********************************************/
// 發送文件到服務器
type SendFileToServer struct {
}
func (this *SendFileToServer) sendFile(filePath string) (err error) {
fileInfo, err := os.Stat(filePath)
if err != nil {
fmt.Println("輸入文件路徑錯誤", err)
return
}
fileName := fileInfo.Name()
fileSize := fileInfo.Size()
fmt.Println("發送的文件名是:", fileName)
var mes message.Message
mes.Type = message.SendFileMesType
open, err := os.Open(filePath)
if err != nil {
fmt.Println(err)
return err
}
defer open.Close()
var count int64
//傳輸數據
for {
buf := make([]byte, 1024)
// 讀取文件內容
readN, err := open.Read(buf)
if err != nil && err == io.EOF {
fmt.Println("文件傳輸完成")
//通知服務器文件傳輸結束
//conn.Write([]byte("finish"))
break
}
//發送到服務端
var fileMes message.SendFileMes
fileMes.FileName = fileName
//多讀取到的文件進行編碼
encodeToString := base64.StdEncoding.EncodeToString(buf[:readN])
fileMes.FileContext = encodeToString
data, err := json.Marshal(fileMes)
if err != nil {
fmt.Println("文件傳輸序列化錯誤", err)
return err
}
mes.Data = string(data)
data, err = json.Marshal(mes)
if err != nil {
fmt.Println("文件傳輸序列化錯誤", err)
return err
}
tr := &utils.Transfer{
Conn: CurUser.Conn,
}
err = tr.WritePkg(data)
count += int64(readN)
sendPercent := float64(count) / float64(fileSize) * 100
value := fmt.Sprintf("%.2f", sendPercent)
//打印上傳進度
fmt.Println("文件上傳:" + value + "%")
}
return
}
服務端
func (this *SendFileProcess) ReceiveFile(mes *message.Message) (err error) {
var fileMes message.SendFileMes
err = json.Unmarshal([]byte(mes.Data), &fileMes)
if err != nil {
fmt.Println("~ReceiveFile~", err)
return
}
fmt.Println("傳輸的文件是:", fileMes.FileName)
openFile, err := os.OpenFile("d:/pic/"+utils2.GetDateStr()+fileMes.FileName, os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
fmt.Println("打開文件錯誤", err)
return
}
defer openFile.Close()
//發送使用了base64 編碼,現在解碼
decodeString, err := base64.StdEncoding.DecodeString(fileMes.FileContext)
if err != nil {
fmt.Println("服務器接收文件base64解碼錯誤", err)
return
}
openFile.Write(decodeString)
return
}
其餘代碼