代码拉取完成,页面将自动刷新
package wheatClient
import (
"errors"
"fmt"
"github.com/timedb/wheatDFS/app"
"github.com/timedb/wheatDFS/etc"
"github.com/timedb/wheatDFS/fileKeyTorch"
"io"
)
var (
HashErr = errors.New("the given hash error")
TokenErr = errors.New("token")
MaxFileTransErr = errors.New("this method only handles large files. For small files, use the Client interface")
UpLoadStateErr = errors.New("this token is not an upload type token")
DownloadStateErr = errors.New("this token is not an download type token")
SwitchErr = errors.New("only upload mode can be switched to download mode")
)
const (
download = 1
upload = 2
workEnd = 3
defaultOffset = -9
//最大下载协程数
proto = 6
)
// FileTransferManager 大文件文件上传器
type FileTransferManager struct {
offset int64
Hash string
Token string
state int
Ext string
host *etc.Addr //服务地址
//上传用结构体
uploadReq *app.StoUploadMaxFileReq
uploadResp *app.StoUploadMaxFileResp
//下载用结构体
downloadResp *app.StoGetMaxFileResp
downloadReq *app.StoGetMaxFileReq
}
//开始传输
func (f *FileTransferManager) startUpload() error {
req := app.MakeStoUploadMaxFileReq()
resp := new(app.StoUploadMaxFileResp)
req.TransferStatus = app.UpStart
req.Hash = f.Hash
req.Ext = f.Ext
//请求
err := req.Do(f.host, resp)
if err != nil {
return err
}
if !resp.Successful() {
return errors.New(resp.Err)
}
f.offset = resp.Offset //修改偏移
f.uploadReq = req
f.uploadResp = resp
return nil
}
// Upload 大文件上传接口
func (f *FileTransferManager) Upload(buf []byte) error {
if f.state != upload {
return UpLoadStateErr
}
if f.offset == defaultOffset {
err := f.startUpload()
if err != nil {
return err
}
}
//构建传输
f.uploadReq.Offset = f.offset
f.uploadReq.TransferStatus = app.UpSustain
f.uploadReq.Content = buf
err := f.uploadReq.Do(f.host, f.uploadResp)
if err != nil {
return err
}
if !f.uploadResp.Successful() {
return errors.New(f.uploadResp.Err)
}
f.offset = f.uploadResp.Offset //修改偏移
return nil
}
// UploadEnd 传输完成
func (f *FileTransferManager) UploadEnd() (string, error) {
if f.state != upload {
return "", UpLoadStateErr
}
f.uploadReq.TransferStatus = app.UpEnd
err := f.uploadReq.Do(f.host, f.uploadResp)
if err != nil {
return "", err
}
if !f.uploadResp.Successful() {
return "", errors.New(f.uploadResp.Err)
}
f.state = workEnd
return f.uploadResp.Token, nil
}
func (f *FileTransferManager) DownLoad() ([]byte, error) {
if f.state != download {
return nil, DownloadStateErr
}
// 下载
f.downloadReq.Offset = f.offset
err := f.downloadReq.Do(f.host, f.downloadResp)
if f.downloadReq.Offset == -1 {
f.state = workEnd
return nil, io.EOF
}
if err != nil {
return nil, err
}
if !f.downloadResp.Successful() {
return nil, errors.New(f.uploadResp.Err)
}
f.offset = f.downloadResp.Offset
return f.downloadResp.Content, err
}
// SwitchToDownloadMode 切换到下载模式
func (f *FileTransferManager) SwitchToDownloadMode() error {
if f.state != upload {
return SwitchErr
}
f.state = download
f.downloadResp = new(app.StoGetMaxFileResp)
f.downloadReq = app.MakeGetMaxFile(f.Token)
f.offset = 0
f.uploadReq = nil
f.uploadResp = nil
host, err := sysClient.getEsoOkHost(f.Token)
if err != nil {
return err
}
f.host = host
return nil
}
// MakeFileTransferManagerByHash 创建文件令牌, 使用hash
func MakeFileTransferManagerByHash(Hash string, Ext string) (*FileTransferManager, error) {
fk := fileKeyTorch.MakeFileKeyByHash(Hash, Ext)
if fk == nil {
return nil, HashErr
}
if fk.Types() != fileKeyTorch.MaxFile {
return nil, MaxFileTransErr
}
host, err := sysClient.GetStorageAddr()
if err != nil {
return nil, err
}
file := new(FileTransferManager)
file.Token = fk.GeyToken()
file.Hash = Hash
file.offset = defaultOffset
file.state = upload
file.Ext = fk.Ext()
file.host = host
file.uploadReq = new(app.StoUploadMaxFileReq)
file.uploadResp = new(app.StoUploadMaxFileResp)
return file, nil
}
// MakeFileTransferManagerByToken 创建下载令牌使用token
func MakeFileTransferManagerByToken(token string) (*FileTransferManager, error) {
fk := fileKeyTorch.MakeFileKeyByToken(token)
if fk == nil {
return nil, TokenErr
}
file := new(FileTransferManager)
file.Token = fk.GeyToken()
host, err := sysClient.getEsoOkHost(file.Token)
if err != nil {
return nil, err
}
file.offset = 0
file.state = download
file.Ext = fk.Ext()
file.host = host
file.downloadReq = app.MakeGetMaxFile(token)
file.downloadResp = new(app.StoGetMaxFileResp)
return file, nil
}
// downProto 高速下载器
type downProto struct {
buf chan []byte //高速下载器
ofCont int64
offset int64
token string
req *app.StoGetMaxFileReq
resp *app.StoGetMaxFileResp
_close bool
}
// 获取管道数据
func (d *downProto) getBuf() ([]byte, bool) {
buf, ok := <-d.buf
return buf, ok
}
// 开始下载
func (d *downProto) start(initOffice int64, token string, host *etc.Addr) {
//开启下载协程
d.req = app.MakeGetMaxFile(d.token)
d.resp = new(app.StoGetMaxFileResp)
d.buf = make(chan []byte, 5)
d.offset = initOffice
d.token = token
d.ofCont = proto
d._close = false
d.req.Token = d.token
go func() {
for true {
d.req.Offset = d.offset //更新变化
err := d.req.Do(host, d.resp)
if err != nil { //错误关闭管道
close(d.buf)
fmt.Println(1, err)
return
}
if !d.resp.Successful() {
close(d.buf)
return
}
if d.resp.Offset == -1 { //结束
close(d.buf)
return
}
d.buf <- d.resp.Content
d.offset += d.ofCont //更新偏移
}
}()
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。