Go语言实现文件的断点续传
Posted Yuan_sr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言实现文件的断点续传相关的知识,希望对你有一定的参考价值。
本文主要简单实现一个发送文件的端点续传功能,主要解决在传输过程中客户端断开后在重新取得连接后可在之前的传输基础上进行继续传输,直到文件传输完毕。
客户端
package main
import (
"fmt"
"io"
"net"
"os"
"strconv"
"time"
)
func clientRead(conn net.Conn) int{
buf := make([]byte, 10)
n, err := conn.Read(buf)
if err != nil {
fmt.Println("conn.Read err:", err)
}
off, err := strconv.Atoi(string(buf[:n]))
if err != nil {
fmt.Println("strconv.Atoi err:", err)
}
return off
}
//发送数据
func clientWrite(conn net.Conn, data []byte){
_, err := conn.Write(data)
if err != nil {
fmt.Println("conn.Write err:", err)
}
fmt.Println("写入数据:", string(data))
}
func clientConn(conn net.Conn) {
defer conn.Close()
clientWrite(conn, []byte("start-->"))
off := clientRead(conn)
fp, err := os.OpenFile("file.txt", os.O_RDONLY, 0777)
if err != nil {
fmt.Println("os.OpenFile err:", err)
}
defer fp.Close()
_, err = fp.Seek(int64(off), 0)
if err != nil {
fmt.Println("Seek err:", err)
}
for{
data := make([]byte, 10)
n, err := fp.Read(data)
if err != nil {
if err == io.EOF{
time.Sleep(time.Second)
//clientWrite(conn, []byte("<--end"))
fmt.Println("文件发送结束!")
break
}
}
//time.Sleep(time.Second)
clientWrite(conn, data[:n])
}
}
func main(){
conn, err := net.DialTimeout("tcp", "127.0.0.1:8848", time.Second*10)
//conn, err := net.Dial("tcp", "127.0.0.1:8848")
if err != nil {
fmt.Println("Dial err:", err)
}
clientConn(conn)
}
服务端
package main
import (
"fmt"
"io"
"net"
"os"
"strconv"
)
//追加
func WriteFile(content []byte){
if len(content) > 0{
fp, err := os.OpenFile("file_out.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0777)
if err != nil {
fmt.Println("OpenFile err:", err)
}
defer fp.Close()
_, err = fp.Write(content)
if err != nil {
fmt.Println("fp.Write err:", err)
}
fmt.Println("fp.Write ok")
}
}
//判断文件是否存在
func getFileState() int64{
stat, err := os.Stat("file_out.txt")
if err != nil {
if os.IsNotExist(err){
fmt.Println("文件不存在")
return 0
}
}
return stat.Size()
}
func serverConn(conn net.Conn){
defer conn.Close()
for true {
var buf = make([]byte, 10)
n, err := conn.Read(buf)
if err != nil {
if err == io.EOF{
fmt.Println("server is EOF")
return
}
fmt.Println("conn.read err:", err)
return
}
fmt.Println("收到数据:", string(buf[:n]))
switch string(buf[:n]) {
case "start-->":
off := getFileState()
stroff := strconv.FormatInt(off, 10)
_, err := conn.Write([]byte(stroff))
if err != nil {
fmt.Println("conn.Write err:", err)
}
continue
//case "<--end":
// fmt.Println("文件写入完毕!")
// return
}
WriteFile(buf[:n])
}
}
func main(){
listen, err := net.Listen("tcp", "127.0.0.1:8848")
if err != nil {
fmt.Println("net.Listen err:", err)
}
fmt.Println("正在监听...")
defer listen.Close()
conn, err := listen.Accept()
if err != nil {
fmt.Println("Accept err:", err)
}
serverConn(conn)
}
以上是关于Go语言实现文件的断点续传的主要内容,如果未能解决你的问题,请参考以下文章