Browse Source

`weed download` command use stream download the large file.

pull/224/head
tnextday 9 years ago
parent
commit
b177afc326
  1. 4
      go/operation/chunked_file.go
  2. 5
      go/util/http_util.go
  3. 94
      go/weed/download.go

4
go/operation/chunked_file.go

@ -83,10 +83,6 @@ func (cm *ChunkManifest) DeleteChunks(master string) error {
return nil return nil
} }
//func (cm *ChunkManifest) StoredHelper() error {
// return nil
//}
func readChunkNeedle(fileUrl string, w io.Writer, offset int64) (written int64, e error) { func readChunkNeedle(fileUrl string, w io.Writer, offset int64) (written int64, e error) {
req, err := http.NewRequest("GET", fileUrl, nil) req, err := http.NewRequest("GET", fileUrl, nil)
if err != nil { if err != nil {

5
go/util/http_util.go

@ -136,12 +136,11 @@ func GetUrlStream(url string, values url.Values, readFn func(io.Reader) error) e
return readFn(r.Body) return readFn(r.Body)
} }
func DownloadUrl(fileUrl string) (filename string, content []byte, e error) {
func DownloadUrl(fileUrl string) (filename string, rc io.ReadCloser, e error) {
response, err := client.Get(fileUrl) response, err := client.Get(fileUrl)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
defer response.Body.Close()
contentDisposition := response.Header["Content-Disposition"] contentDisposition := response.Header["Content-Disposition"]
if len(contentDisposition) > 0 { if len(contentDisposition) > 0 {
if strings.HasPrefix(contentDisposition[0], "filename=") { if strings.HasPrefix(contentDisposition[0], "filename=") {
@ -149,7 +148,7 @@ func DownloadUrl(fileUrl string) (filename string, content []byte, e error) {
filename = strings.Trim(filename, "\"") filename = strings.Trim(filename, "\"")
} }
} }
content, e = ioutil.ReadAll(response.Body)
rc = response.Body
return return
} }

94
go/weed/download.go

@ -3,9 +3,11 @@ package main
import ( import (
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "os"
"path" "path"
"io/ioutil"
"strings" "strings"
"github.com/chrislusf/seaweedfs/go/operation" "github.com/chrislusf/seaweedfs/go/operation"
@ -43,50 +45,76 @@ var cmdDownload = &Command{
func runDownload(cmd *Command, args []string) bool { func runDownload(cmd *Command, args []string) bool {
for _, fid := range args { for _, fid := range args {
filename, content, e := fetchFileId(*d.server, fid)
if e != nil {
fmt.Println("Fetch Error:", e)
continue
if e := downloadToFile(*d.server, fid, *d.dir); e != nil {
fmt.Println("Download Error:", e)
} }
if filename == "" {
filename = fid
}
return true
}
func downloadToFile(server, fileId, saveDir string) error {
fileUrl, lookupError := operation.LookupFileId(server, fileId)
if lookupError != nil {
return lookupError
}
filename, rc, err := util.DownloadUrl(fileUrl)
if err != nil {
return err
}
defer rc.Close()
if filename == "" {
filename = fileId
}
isFileList := false
if strings.HasSuffix(filename, "-list") {
// old command compatible
isFileList = true
filename = filename[0 : len(filename)-len("-list")]
}
f, err := os.OpenFile(path.Join(saveDir, filename), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
if err != nil {
return err
}
defer f.Close()
if isFileList {
content, err := ioutil.ReadAll(rc)
if err != nil {
return err
} }
if strings.HasSuffix(filename, "-list") {
filename = filename[0 : len(filename)-len("-list")]
fids := strings.Split(string(content), "\n")
f, err := os.OpenFile(path.Join(*d.dir, filename), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
if err != nil {
fmt.Println("File Creation Error:", e)
continue
fids := strings.Split(string(content), "\n")
for _, partId := range fids {
var n int
_, part, err := fetchContent(*d.server, partId)
if err == nil {
n, err = f.Write(part)
} }
defer f.Close()
for _, partId := range fids {
var n int
_, part, err := fetchFileId(*d.server, partId)
if err == nil {
n, err = f.Write(part)
}
if err == nil && n < len(part) {
err = io.ErrShortWrite
}
if err != nil {
fmt.Println("File Write Error:", err)
break
}
if err == nil && n < len(part) {
err = io.ErrShortWrite
} }
} else {
ioutil.WriteFile(path.Join(*d.dir, filename), content, os.ModePerm)
if err != nil {
return err
}
}
} else {
if _, err = io.Copy(f, rc); err != nil {
return err
} }
} }
return true
return nil
} }
func fetchFileId(server string, fileId string) (filename string, content []byte, e error) {
func fetchContent(server string, fileId string) (filename string, content []byte, e error) {
fileUrl, lookupError := operation.LookupFileId(server, fileId) fileUrl, lookupError := operation.LookupFileId(server, fileId)
if lookupError != nil { if lookupError != nil {
return "", nil, lookupError return "", nil, lookupError
} }
filename, content, e = util.DownloadUrl(fileUrl)
var rc io.ReadCloser
if filename, rc, e = util.DownloadUrl(fileUrl); e != nil {
return "", nil, e
}
content, e = ioutil.ReadAll(rc)
rc.Close()
return return
} }

Loading…
Cancel
Save