mirror of
https://github.com/qjfoidnh/BaiduPCS-Go.git
synced 2026-06-04 09:54:22 +08:00
v3.9.9
- 最大上传单文件支持至128G - 上传速度优化 - 下载取消文件预分配 - 因官方接口变动上传文件强制计算秒传 - transfer命令修复--download参数
This commit is contained in:
11
README.md
11
README.md
@@ -88,12 +88,19 @@ iikira/BaiduPCS-Go was largely inspired by [GangZhuo/BaiduPCS](https://github.co
|
||||
|
||||
[下载](#下载文件目录)网盘内文件, 支持多个文件或目录下载, 支持断点续传和单文件并行下载;
|
||||
|
||||
[上传](#上传文件目录)本地文件, 支持上传大文件, 支持多个文件或目录上传;
|
||||
[上传](#上传文件目录)本地文件, 支持上传最大128G大文件, 支持多个文件或目录上传;
|
||||
|
||||
[转存](#转存文件目录)其他用户分享的文件, 支持带密码的分享链接;
|
||||
|
||||
[离线下载](#离线下载), 支持http/https/ftp/电驴/磁力链协议.
|
||||
# 版本更新
|
||||
**2025.08.29** v3.9.9
|
||||
- 最大上传单文件支持至128G
|
||||
- 上传速度优化
|
||||
- 下载取消文件预分配
|
||||
- 因官方接口变动上传文件强制计算秒传
|
||||
- transfer命令修复--download参数
|
||||
|
||||
**2025.08.29** v3.9.8
|
||||
- 全面修复了上传文件的问题
|
||||
- 全面修复了下载文件的问题
|
||||
@@ -910,7 +917,7 @@ c4.pcs.baidu.com
|
||||
c5.pcs.baidu.com
|
||||
d.pcs.baidu.com
|
||||
```
|
||||
最新版上传时支持动态获取pcs服务器, 理论上不需要手动配置
|
||||
v3.9.8后上传时支持动态获取pcs服务器, 理论上不需要手动配置. 如希望使用静态pcs服务器, 可配置打开`fix_pcs_addr`
|
||||
|
||||
`cache_size` 的值支持可选设置单位了, 单位不区分大小写, `b` 和 `B` 均表示字节的意思, 如 `64KB`, `1MB`, `32kb`, `65536b`, `65536`.
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ type (
|
||||
pcsAddr string
|
||||
panUA string
|
||||
isSetPanUA bool
|
||||
fixPCSAddr bool
|
||||
ph *panhome.PanHome
|
||||
cacheOpMap cachemap.CacheOpMap
|
||||
}
|
||||
@@ -377,6 +378,10 @@ func (pcs *BaiduPCS) SetHTTPS(https bool) {
|
||||
pcs.isHTTPS = https
|
||||
}
|
||||
|
||||
func (pcs *BaiduPCS) SetStaticPCSAddr(static bool) {
|
||||
pcs.fixPCSAddr = static
|
||||
}
|
||||
|
||||
// URL 返回 url
|
||||
func (pcs *BaiduPCS) URL() *url.URL {
|
||||
host := pcs.pcsAddr
|
||||
|
||||
@@ -66,7 +66,7 @@ func (pcs *BaiduPCS) getLocateDownloadLink(pcspath string) (link string, pcsErro
|
||||
func (pcs *BaiduPCS) ExportByFileInfo(finfo *FileDirectory) (rinfo *RapidUploadInfo, pcsError pcserror.Error) {
|
||||
errInfo := pcserror.NewPCSErrorInfo(OperationExportFileInfo)
|
||||
errInfo.ErrType = pcserror.ErrTypeOthers
|
||||
if finfo.Size > MaxRapidUploadSize {
|
||||
if finfo.Size > MaxUploadSize {
|
||||
errInfo.Err = ErrFileTooLarge
|
||||
return nil, errInfo
|
||||
}
|
||||
@@ -108,7 +108,7 @@ func (pcs *BaiduPCS) GetRapidUploadInfoByFileInfo(finfo *FileDirectory) (rinfo *
|
||||
})
|
||||
|
||||
// 如果是没获取到MD5, 可尝试新接口(测试中), 新接口调用频率有限制且文件大小不能超过约3.9G
|
||||
if pcsError != nil && pcsError.GetError() == ErrGetRapidUploadInfoMD5NotFound && finfo.Size < 4 * converter.GB {
|
||||
if pcsError != nil && pcsError.GetError() == ErrGetRapidUploadInfoMD5NotFound && finfo.Size < 4*converter.GB {
|
||||
link, pcsError = pcs.GetDirectDownloadLink(finfo.Path)
|
||||
rinfo, pcsError = pcs.GetRapidUploadInfoByLink(link, &RapidUploadInfo{
|
||||
ContentLength: finfo.Size,
|
||||
@@ -121,12 +121,11 @@ func (pcs *BaiduPCS) GetRapidUploadInfoByFileInfo(finfo *FileDirectory) (rinfo *
|
||||
func (pcs *BaiduPCS) GetDirectDownloadLink(path string) (link string, pcsError pcserror.Error) {
|
||||
var header = pcs.getPanUAHeader()
|
||||
header["Range"] = "bytes=0-" + strconv.FormatInt(SliceMD5Size-1, 10)
|
||||
RawQuery := map[string] string{"path": path}
|
||||
RawQuery := map[string]string{"path": path}
|
||||
pcsURL := pcs.generatePCSURL("file", "download", RawQuery)
|
||||
return pcsURL.String(), nil
|
||||
}
|
||||
|
||||
|
||||
// GetRapidUploadInfoByLink 通过下载链接, 获取文件秒传信息
|
||||
func (pcs *BaiduPCS) GetRapidUploadInfoByLink(link string, compareRInfo *RapidUploadInfo) (rinfo *RapidUploadInfo, pcsError pcserror.Error) {
|
||||
errInfo := pcserror.NewPCSErrorInfo(OperationGetRapidUploadInfo)
|
||||
@@ -277,7 +276,7 @@ func (pcs *BaiduPCS) FixMD5ByFileInfo(finfo *FileDirectory) (pcsError pcserror.E
|
||||
return errInfo
|
||||
}
|
||||
|
||||
if finfo.Size > MaxRapidUploadSize { // 文件大于20GB
|
||||
if finfo.Size > MaxUploadSize {
|
||||
errInfo.Err = ErrFileTooLarge
|
||||
return errInfo
|
||||
}
|
||||
|
||||
@@ -118,7 +118,10 @@ func (pcs *BaiduPCS) PrepareUK() (dataReadCloser io.ReadCloser, pcsError pcserro
|
||||
// PreparePCSServers 获取推荐的pcs服务器URL
|
||||
func (pcs *BaiduPCS) PreparePCSServers() (dataReadCloser io.ReadCloser, pcsError pcserror.Error) {
|
||||
pcs.lazyInit()
|
||||
pcsURL := pcs.generatePCSURL("file", "locateupload")
|
||||
pcsURL := pcs.generatePCSURL("file", "locateupload", map[string]string{
|
||||
"upload_version": "2.0",
|
||||
"app_id": PanAppID,
|
||||
})
|
||||
baiduPCSVerbose.Infof("%s URL: %s\n", OperationGetPCSServer, pcsURL)
|
||||
|
||||
dataReadCloser, pcsError = pcs.sendReqReturnReadCloser(reqTypePCS, OperationGetPCSServer, http.MethodGet, pcsURL.String(), nil, nil)
|
||||
|
||||
@@ -5,19 +5,30 @@ import (
|
||||
"github.com/qjfoidnh/BaiduPCS-Go/baidupcs/pcserror"
|
||||
"github.com/qjfoidnh/BaiduPCS-Go/pcsutil/converter"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// MinUploadBlockSize 最小的上传的文件分片大小
|
||||
// MaxUploadBlockSize 上传的文件分片最大大小
|
||||
MaxUploadBlockSize = 64 * converter.MB
|
||||
// MiddleUploadBlockSize 上传的文件分片中等大小
|
||||
MiddleUploadBlockSize = 16 * converter.MB
|
||||
// MinUploadBlockSize 上传的文件分片最小大小
|
||||
MinUploadBlockSize = 4 * converter.MB
|
||||
// MaxRapidUploadSize 秒传文件支持的最大文件大小
|
||||
MaxRapidUploadSize = 20 * converter.GB
|
||||
// RecommendedUploadSize 推荐的最高文件上传大小
|
||||
RecommendedUploadSize = 32 * converter.GB
|
||||
// MaxUploadSize 目前支持的最大文件大小
|
||||
MaxUploadSize = 128 * converter.GB
|
||||
// SliceMD5Size 计算 slice-md5 所需的长度
|
||||
SliceMD5Size = 256 * converter.KB
|
||||
// EmptyContentMD5 空串的md5
|
||||
EmptyContentMD5 = "d41d8cd98f00b204e9800998ecf8427e"
|
||||
// MiddleUploadThreshold 中等分片对应的文件大小
|
||||
MiddleUploadThreshold = 8 * converter.GB
|
||||
// MaxUploadThreshold 最大分片对应的文件大小
|
||||
MaxUploadThreshold = 32 * converter.GB
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -71,6 +82,17 @@ type (
|
||||
UploadID string
|
||||
UploadSeqList []*UploadSeq
|
||||
}
|
||||
|
||||
PCSServer struct {
|
||||
ServerAddr string `json:"server"`
|
||||
}
|
||||
|
||||
PCSInfo struct {
|
||||
*pcserror.PCSErrInfo
|
||||
Host string `json:"host"`
|
||||
Server []string `json:"server"`
|
||||
Servers []*PCSServer `json:"servers"`
|
||||
}
|
||||
)
|
||||
|
||||
// RapidUpload 秒传文件
|
||||
@@ -235,3 +257,38 @@ func (pcs *BaiduPCS) UploadPrecreate(targetPath, contentMD5, sliceMD5, crc32 str
|
||||
panic("unknown returntype")
|
||||
}
|
||||
}
|
||||
|
||||
// GetRandomPCSHost 随机获取一个可用的pcs地址
|
||||
func (pcs *BaiduPCS) GetRandomPCSHost() (pcsError pcserror.Error, pcsHost string) {
|
||||
if pcs.fixPCSAddr {
|
||||
return
|
||||
}
|
||||
dataReadCloser, pcsError := pcs.PreparePCSServers()
|
||||
if pcsError != nil {
|
||||
return
|
||||
}
|
||||
defer dataReadCloser.Close()
|
||||
pcsInfo := &PCSInfo{
|
||||
PCSErrInfo: pcserror.NewPCSErrorInfo(OperationGetPCSServer),
|
||||
}
|
||||
pcsError = pcserror.HandleJSONParse(OperationGetPCSServer, dataReadCloser, pcsInfo)
|
||||
if pcsError != nil {
|
||||
return
|
||||
}
|
||||
pcsHostList := make([]string, 0)
|
||||
if len(pcsInfo.Servers) > 0 {
|
||||
for _, server := range pcsInfo.Servers {
|
||||
if strings.Contains(server.ServerAddr, "-") {
|
||||
parsedURL, err := url.Parse(server.ServerAddr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
pcsHostList = append(pcsHostList, parsedURL.Hostname())
|
||||
}
|
||||
}
|
||||
} else if len(pcsInfo.Server) > 0 {
|
||||
pcsHostList = pcsInfo.Server
|
||||
}
|
||||
pcsHost = RandomElement(pcsHostList)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/qjfoidnh/BaiduPCS-Go/pcsutil"
|
||||
"github.com/qjfoidnh/BaiduPCS-Go/pcsutil/converter"
|
||||
"io"
|
||||
"math/rand"
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
@@ -152,3 +153,11 @@ func DecryptMD5(rawMD5 string) string {
|
||||
}
|
||||
return sliceThird[8:16] + sliceThird[0:8] + sliceThird[24:32] + sliceThird[16:24]
|
||||
}
|
||||
|
||||
func RandomElement[T any](s []T) T {
|
||||
if len(s) == 0 {
|
||||
var zero T // 对于空slice,返回类型的零值
|
||||
return zero
|
||||
}
|
||||
return s[rand.Intn(len(s))]
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ func (c *PCSConfig) PrintTable() {
|
||||
[]string{"user_agent", c.UserAgent, requester.DefaultUserAgent, "浏览器标识"},
|
||||
[]string{"pcs_ua", c.PCSUA, "", "PCS 浏览器标识"},
|
||||
[]string{"pcs_addr", c.PCSAddr, "pcs.baidu.com", "PCS 服务器地址"},
|
||||
[]string{"fix_pcs_addr", fmt.Sprint(c.FixPCSAddr), "false", "不使用动态PCS服务器地址, 通常情况保持默认即可"},
|
||||
[]string{"pan_ua", c.PanUA, baidupcs.NetdiskUA, "Pan 浏览器标识"},
|
||||
[]string{"proxy", c.Proxy, "", "设置代理, 支持 http/socks5 代理"},
|
||||
[]string{"local_addrs", c.LocalAddrs, "", "设置本地网卡地址, 多个地址用逗号隔开"},
|
||||
|
||||
@@ -83,7 +83,7 @@ func (c *PCSConfig) manipUser(op string, baiduBase *BaiduBase) (*Baidu, error) {
|
||||
return nil, ErrBaiduUserNotFound
|
||||
}
|
||||
|
||||
//setupNewUser 从已有用户中, 设置新的当前登录用户
|
||||
// setupNewUser 从已有用户中, 设置新的当前登录用户
|
||||
func (c *PCSConfig) setupNewUser(user *Baidu) {
|
||||
if user == nil {
|
||||
return
|
||||
@@ -216,6 +216,14 @@ func (c *PCSConfig) SETPCSAddr(pcsaddr string) bool {
|
||||
return match
|
||||
}
|
||||
|
||||
// SetStaticPCSAddr 设置上传时是否关闭动态PCS域名
|
||||
func (c *PCSConfig) SetStaticPCSAddr(static bool) {
|
||||
c.FixPCSAddr = static
|
||||
if c.pcs != nil {
|
||||
c.pcs.SetStaticPCSAddr(static)
|
||||
}
|
||||
}
|
||||
|
||||
// SetEnableHTTPS 设置是否启用https
|
||||
func (c *PCSConfig) SetEnableHTTPS(https bool) {
|
||||
c.EnableHTTPS = https
|
||||
@@ -253,4 +261,4 @@ func (c *PCSConfig) SetIgnoreIllegal(ignore bool) {
|
||||
// SetForceLogin 设置强制登录
|
||||
func (c *PCSConfig) SetForceLogin(username string) {
|
||||
c.ForceLogin = username
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ type PCSConfig struct {
|
||||
PanUA string `json:"pan_ua"` // PAN浏览器标识
|
||||
SaveDir string `json:"savedir"` // 下载储存路径
|
||||
EnableHTTPS bool `json:"enable_https"` // 启用https
|
||||
FixPCSAddr bool `json:"fix_pcs_addr"` //上传不使用动态PCS服务器域名
|
||||
ForceLogin string `json:"force_login_username"` // 强制登录
|
||||
Proxy string `json:"proxy"` // 代理
|
||||
LocalAddrs string `json:"local_addrs"` // 本地网卡地址
|
||||
|
||||
@@ -23,14 +23,10 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
type PCSInfo struct {
|
||||
*pcserror.PCSErrInfo
|
||||
Host string `json:"host"`
|
||||
Server []string `json:"server"`
|
||||
}
|
||||
|
||||
var client = pcsconfig.Config.PCSHTTPClient()
|
||||
|
||||
var pcsPeriod = 256 // 上传多少个分片更换一次pcsHost
|
||||
|
||||
func (e EmptyReaderLen64) Read(p []byte) (n int, err error) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
@@ -53,43 +49,29 @@ func (pu *PCSUpload) lazyInit() {
|
||||
}
|
||||
|
||||
// Precreate 检查网盘的目标路径是否已存在同名文件及路径合法性, 顺便获取本次上传用的pcs服务器
|
||||
func (pu *PCSUpload) Precreate(fileSize int64, policy string) (pcsHost string, pcsError pcserror.Error) {
|
||||
func (pu *PCSUpload) Precreate(fileSize int64, policy string) (originPCSHost string, pcsError pcserror.Error) {
|
||||
pcsError = pu.pcs.CheckIsdir(baidupcs.OperationUpload, pu.targetPath, policy, fileSize)
|
||||
if pcsError != nil {
|
||||
return
|
||||
}
|
||||
|
||||
dataReadCloser, pcsError := pu.pcs.PreparePCSServers()
|
||||
if pcsError != nil {
|
||||
return
|
||||
}
|
||||
defer dataReadCloser.Close()
|
||||
pcsInfo := &PCSInfo{
|
||||
PCSErrInfo: pcserror.NewPCSErrorInfo(baidupcs.OperationGetPCSServer),
|
||||
}
|
||||
pcsError = pcserror.HandleJSONParse(baidupcs.OperationGetPCSServer, dataReadCloser, pcsInfo)
|
||||
if pcsError != nil {
|
||||
return
|
||||
}
|
||||
if len(pcsInfo.Server) > 0 {
|
||||
pcsHost = pcsInfo.Server[0]
|
||||
} else {
|
||||
pcsHost = pcsInfo.Host
|
||||
}
|
||||
|
||||
originPCSHost = pu.pcs.GetPCSAddr()
|
||||
_, newPCSHost := pu.pcs.GetRandomPCSHost()
|
||||
pu.pcs.SetPCSAddr(newPCSHost)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func (pu *PCSUpload) TmpFile(ctx context.Context, pcsHost, uploadId, targetPath string, partSeq int, partOffset int64, r rio.ReaderLen64) (checksum string, uperr error) {
|
||||
func (pu *PCSUpload) TmpFile(ctx context.Context, uploadId, targetPath string, partSeq int, partOffset int64, r rio.ReaderLen64) (checksum string, uperr error) {
|
||||
pu.lazyInit()
|
||||
|
||||
var respErr *uploader.MultiError
|
||||
|
||||
// 临时切换为动态pcs addr
|
||||
originPCSHost := pu.pcs.GetPCSAddr()
|
||||
defer pu.pcs.SetPCSAddr(originPCSHost)
|
||||
pu.pcs.SetPCSAddr(pcsHost)
|
||||
if partSeq%pcsPeriod == pcsPeriod-1 {
|
||||
go func() {
|
||||
_, newPCSHost := pu.pcs.GetRandomPCSHost()
|
||||
pu.pcs.SetPCSAddr(newPCSHost)
|
||||
}()
|
||||
}
|
||||
|
||||
checksum, pcsError := pu.pcs.UploadTmpFile(uploadId, targetPath, partSeq, partOffset, func(uploadURL string, jar http.CookieJar) (resp *http.Response, err error) {
|
||||
client.SetCookiejar(jar)
|
||||
@@ -132,7 +114,8 @@ func (pu *PCSUpload) TmpFile(ctx context.Context, pcsHost, uploadId, targetPath
|
||||
return checksum, pcsError
|
||||
}
|
||||
|
||||
func (pu *PCSUpload) CreateSuperFile(uploadId string, fileSize int64, checksumMap map[int]string) (err error) {
|
||||
func (pu *PCSUpload) CreateSuperFile(pcsHost, uploadId string, fileSize int64, checksumMap map[int]string) (err error) {
|
||||
pu.lazyInit()
|
||||
pu.pcs.SetPCSAddr(pcsHost) // 恢复默认pcs服务器
|
||||
return pu.pcs.UploadCreateSuperFile(uploadId, fileSize, pu.targetPath, checksumMap)
|
||||
}
|
||||
|
||||
@@ -83,12 +83,10 @@ func (utu *UploadTaskUnit) prepareFile() {
|
||||
}
|
||||
|
||||
// 秒传不分文件大小一律进行
|
||||
if utu.LocalFileChecksum.Length >= baidupcs.RecommendedUploadSize {
|
||||
fmt.Printf("[%s] 文件超过32GB, 上传有可能失败, 建议分割文件...\n", utu.taskInfo.Id())
|
||||
}
|
||||
|
||||
//if utu.LocalFileChecksum.Length > baidupcs.MaxRapidUploadSize {
|
||||
// fmt.Printf("[%s] 文件超过20GB, 无法使用秒传功能, 跳过秒传...\n", utu.taskInfo.Id())
|
||||
// utu.Step = StepUploadUpload
|
||||
// return
|
||||
//}
|
||||
// 下一步: 秒传
|
||||
utu.Step = StepUploadRapidUpload
|
||||
}
|
||||
@@ -123,7 +121,7 @@ func (utu *UploadTaskUnit) rapidUpload() (isContinue bool, result *taskframework
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("[%s] 检测秒传中, 请稍候...\n", utu.taskInfo.Id())
|
||||
fmt.Printf("[%s] 开始计算文件元信息, 请稍候...\n", utu.taskInfo.Id())
|
||||
|
||||
// 经测试, 文件的 crc32 值并非秒传文件所必需
|
||||
err := utu.LocalFileChecksum.Sum(checksum.CHECKSUM_MD5 | checksum.CHECKSUM_SLICE_MD5)
|
||||
@@ -170,9 +168,9 @@ func (utu *UploadTaskUnit) rapidUpload() (isContinue bool, result *taskframework
|
||||
}
|
||||
b64Content := strings.TrimRight(base64.StdEncoding.EncodeToString(dataContent), "=")
|
||||
|
||||
blockSize := getBlockSize()
|
||||
blockSize := getBlockSize(utu.LocalFileChecksum.Length)
|
||||
|
||||
fmt.Printf("[%s] 开始计算文件分块md5...\n", utu.taskInfo.Id())
|
||||
fmt.Printf("[%s] 开始计算文件分块md5, 请稍候...\n", utu.taskInfo.Id())
|
||||
err = utu.LocalFileChecksum.CalculateChunkedSum(blockSize)
|
||||
if err != nil {
|
||||
// 不重试
|
||||
@@ -206,7 +204,7 @@ func (utu *UploadTaskUnit) rapidUpload() (isContinue bool, result *taskframework
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("[%s] 秒传失败, 开始上传文件...\n\n", utu.taskInfo.Id())
|
||||
fmt.Printf("[%s] 开始上传文件...\n\n", utu.taskInfo.Id())
|
||||
|
||||
// 保存秒传信息
|
||||
utu.UploadingDatabase.UpdateUploading(&utu.LocalFileChecksum.LocalFileMeta, nil)
|
||||
@@ -219,7 +217,7 @@ func (utu *UploadTaskUnit) rapidUpload() (isContinue bool, result *taskframework
|
||||
func (utu *UploadTaskUnit) upload() (result *taskframework.TaskUnitRunResult) {
|
||||
utu.Step = StepUploadUpload
|
||||
|
||||
blockSize := getBlockSize()
|
||||
blockSize := getBlockSize(utu.LocalFileChecksum.Length)
|
||||
|
||||
muer := uploader.NewMultiUploader(NewPCSUpload(utu.PCS, utu.SavePath), rio.NewFileReaderAtLen64(utu.LocalFileChecksum.GetFile()), &uploader.MultiUploaderConfig{
|
||||
Parallel: utu.Parallel,
|
||||
@@ -372,6 +370,11 @@ func (utu *UploadTaskUnit) RetryWait() time.Duration {
|
||||
func (utu *UploadTaskUnit) Run() (result *taskframework.TaskUnitRunResult) {
|
||||
fmt.Printf("[%s] 准备上传: %s\n", utu.taskInfo.Id(), utu.LocalFileChecksum.Path)
|
||||
|
||||
if utu.LocalFileChecksum.Length > baidupcs.MaxUploadSize {
|
||||
fmt.Printf("[%s] 文件大小超过128G, 无法上传, 跳过...\n", utu.taskInfo.Id())
|
||||
return
|
||||
}
|
||||
|
||||
err := utu.LocalFileChecksum.OpenPath()
|
||||
if err != nil {
|
||||
fmt.Printf("[%s] 文件不可读, 错误信息: %s, 跳过...\n", utu.taskInfo.Id(), err)
|
||||
|
||||
@@ -8,8 +8,15 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func getBlockSize() int64 {
|
||||
return baidupcs.MinUploadBlockSize
|
||||
func getBlockSize(fileSize int64) int64 {
|
||||
blockSize := baidupcs.MinUploadBlockSize
|
||||
if fileSize >= baidupcs.MiddleUploadThreshold {
|
||||
blockSize = baidupcs.MiddleUploadBlockSize
|
||||
}
|
||||
if fileSize >= baidupcs.MaxUploadThreshold {
|
||||
blockSize = baidupcs.MaxUploadBlockSize
|
||||
}
|
||||
return blockSize
|
||||
}
|
||||
|
||||
func creaetDataOffset(contentMD5 string, uk, dataTime, fileSize, subSize int64) (offset int64, err error) {
|
||||
|
||||
7
main.go
7
main.go
@@ -55,7 +55,7 @@ const (
|
||||
|
||||
var (
|
||||
// Version 版本号
|
||||
Version = "v3.9.8-devel"
|
||||
Version = "v3.9.9-devel"
|
||||
|
||||
historyFilePath = filepath.Join(pcsconfig.GetConfigDir(), "pcs_command_history.txt")
|
||||
reloadFn = func(c *cli.Context) error {
|
||||
@@ -154,7 +154,7 @@ func main() {
|
||||
lineArgs = args.Parse(line)
|
||||
numArgs = len(lineArgs)
|
||||
acceptCompleteFileCommands = []string{
|
||||
"cd", "cp", "download", "export", "fixmd5", "locate", "ls", "meta", "mkdir", "mv", "rapidupload", "rm", "setastoken", "share", "transfer", "tree", "upload",
|
||||
"cd", "cp", "download", "export", "locate", "ls", "meta", "mkdir", "mv", "rm", "setastoken", "share", "transfer", "tree", "upload",
|
||||
}
|
||||
closed = strings.LastIndex(line, " ") == len(line)-1
|
||||
)
|
||||
@@ -1803,6 +1803,9 @@ func main() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if c.IsSet("fix_pcs_addr") {
|
||||
pcsconfig.Config.SetStaticPCSAddr(c.Bool("fix_pcs_addr"))
|
||||
}
|
||||
if c.IsSet("pan_ua") {
|
||||
pcsconfig.Config.SetPanUA(c.String("pan_ua"))
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
const (
|
||||
// DefaultBufSize 默认的bufSize
|
||||
DefaultBufSize = int(256 * converter.KB)
|
||||
DefaultBufSize = int(1 * converter.MB)
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -260,7 +260,7 @@ func (lfc *LocalFileChecksum) CalculateChunkedSum(chunkSize int64) (err error) {
|
||||
lfc.BlocksList = make([]string, 0, chunkCount)
|
||||
|
||||
// 分块处理
|
||||
buffer := make([]byte, 64*1024) // 64KB读取缓冲区
|
||||
buffer := make([]byte, 4*converter.MB) // 4MB读取缓冲区
|
||||
chunkMD5 := md5.New()
|
||||
for offset := int64(0); offset < fileSize; offset += chunkSize {
|
||||
// 计算当前分块的实际大小(最后一块可能较小)
|
||||
|
||||
@@ -16,8 +16,8 @@ type (
|
||||
// MultiUpload 支持多线程的上传, 可用于断点续传
|
||||
MultiUpload interface {
|
||||
Precreate(fileSize int64, policy string) (pcsHost string, err pcserror.Error)
|
||||
TmpFile(ctx context.Context, pcsHost, uploadid, targetPath string, partseq int, partOffset int64, readerlen64 rio.ReaderLen64) (checksum string, terr error)
|
||||
CreateSuperFile(uploadId string, fileSize int64, checksumMap map[int]string) (cerr error)
|
||||
TmpFile(ctx context.Context, uploadid, targetPath string, partseq int, partOffset int64, readerlen64 rio.ReaderLen64) (checksum string, terr error)
|
||||
CreateSuperFile(pcsHost, uploadId string, fileSize int64, checksumMap map[int]string) (cerr error)
|
||||
}
|
||||
|
||||
// MultiUploader 多线程上传
|
||||
|
||||
@@ -39,7 +39,7 @@ func (werl *workerList) Readed() int64 {
|
||||
}
|
||||
|
||||
func (muer *MultiUploader) upload() (uperr error) {
|
||||
pcsHost, err := muer.multiUpload.Precreate(muer.file.Len(), muer.config.Policy)
|
||||
originPCSHost, err := muer.multiUpload.Precreate(muer.file.Len(), muer.config.Policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -79,7 +79,7 @@ func (muer *MultiUploader) upload() (uperr error) {
|
||||
terr error
|
||||
)
|
||||
go func() {
|
||||
checksum, terr = muer.multiUpload.TmpFile(ctx, pcsHost, muer.uploadid, muer.targetPath, wer.id, wer.partOffset, wer.splitUnit)
|
||||
checksum, terr = muer.multiUpload.TmpFile(ctx, muer.uploadid, muer.targetPath, wer.id, wer.partOffset, wer.splitUnit)
|
||||
close(doneChan)
|
||||
}()
|
||||
select {
|
||||
@@ -135,7 +135,7 @@ func (muer *MultiUploader) upload() (uperr error) {
|
||||
default:
|
||||
}
|
||||
|
||||
cerr := muer.multiUpload.CreateSuperFile(muer.uploadid, muer.file.Len(), checksumMap)
|
||||
cerr := muer.multiUpload.CreateSuperFile(originPCSHost, muer.uploadid, muer.file.Len(), checksumMap)
|
||||
if cerr != nil {
|
||||
return cerr
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"FileVersion": {
|
||||
"Major": 3,
|
||||
"Minor": 9,
|
||||
"Patch": 8,
|
||||
"Patch": 9,
|
||||
"Build": 0
|
||||
},
|
||||
"ProductVersion": {
|
||||
"Major": 3,
|
||||
"Minor": 9,
|
||||
"Patch": 8,
|
||||
"Patch": 9,
|
||||
"Build": 0
|
||||
},
|
||||
"FileFlagsMask": "3f",
|
||||
@@ -22,14 +22,14 @@
|
||||
"Comments": "",
|
||||
"CompanyName": "qjfoidnh",
|
||||
"FileDescription": "百度网盘客户端(加强版)",
|
||||
"FileVersion": "v3.9.8",
|
||||
"FileVersion": "v3.9.9",
|
||||
"InternalName": "",
|
||||
"LegalCopyright": "© 2018-2025 qjfoidnh.",
|
||||
"LegalTrademarks": "",
|
||||
"OriginalFilename": "",
|
||||
"PrivateBuild": "",
|
||||
"ProductName": "BaiduPCS-Go",
|
||||
"ProductVersion": "v3.9.8",
|
||||
"ProductVersion": "v3.9.9",
|
||||
"SpecialBuild": ""
|
||||
},
|
||||
"VarFileInfo": {
|
||||
|
||||
Reference in New Issue
Block a user