运行环境: Mac os X and Linux
现在当前目录下创建qiniu.json文件:
{ "AK":"XXX" , "SK":"XXX", "BN":"xx" }
package main import ( "encoding/json" "fmt" "io/ioutil" "os" "path" "strings" ) import ( . "github.com/qiniu/api/conf" "github.com/qiniu/api/io" "github.com/qiniu/api/rs" "github.com/qiniu/log" ) import ( "etag" ) var uptoken string var buckName string var currentDir string func init() { currentDir, _ = os.Getwd() file, err := os.Open(currentDir + "/" + "qiniu.json") // For read access. if err != nil { log.Fatal(err) } configFromFile, _ := ioutil.ReadAll(file) var conf config err = json.Unmarshal([]byte(configFromFile), &conf) if err != nil { fmt.Println("error:", err) } ACCESS_KEY = conf.AK SECRET_KEY = conf.SK buckName = conf.BN uptoken = getUpToken(buckName) } type config struct { AK string SK string BN string } func main() { filePathArgs := os.Args[1] if filePathArgs == "" { fmt.Println("please input the file's path") } filePath := filePathArgs if !strings.ContainsRune(filePathArgs, '/') { filePath = currentDir + "/" + filePathArgs } etag, err := etag.GetEtag(filePath) if err != nil { fmt.Fprintln(os.Stderr, err) return } fileSuffix := getSuffix(filePath) fmt.Println("etag:" + etag) key := etag + fileSuffix doUpload(filePath, key) } //genereate uptoken for uploading to qiniu func getUpToken(bucketName string) string { putPolicy := rs.PutPolicy{ Scope: bucketName, //CallbackUrl: callbackUrl, //CallbackBody:callbackBody, //ReturnUrl: returnUrl, //ReturnBody: returnBody, //AsyncOps: asyncOps, //EndUser: endUser, //Expires: expires, } return putPolicy.Token(nil) } func doUpload(localFile string, key string) { var err error var ret io.PutRet var extra = &io.PutExtra{ //Params: params, //MimeType: mieType, //Crc32: crc32, CheckCrc: 0, } // ret 变量用于存取返回的信息,详情见 io.PutRet // uptoken 为业务服务器生成的上传口令 // key 为文件存储的标识 // localFile 为本地文件名 // extra 为上传文件的额外信息,详情见 io.PutExtra,可选 err = io.PutFile(nil, &ret, uptoken, key, localFile, extra) if err != nil { //上传产生错误 log.Print("io.PutFile failed:", err) return } //上传成功,处理返回值 //fmt.Println("hash:", ret.Hash, "key:", ret.Key) fileUrl := "http://" + buckName + ".qiniudn.com/" + ret.Key fmt.Println("file's url:") fmt.Println(fileUrl) } func getSuffix(filePath string) string { fileNameWithSuffix := path.Base(filePath) fileSuffix := path.Ext(fileNameWithSuffix) return fileSuffix }
package etag import ( "bytes" "crypto/sha1" "encoding/base64" //"fmt" "io" "os" ) const ( BLOCK_BITS = 22 // Indicate that the blocksize is 4M BLOCK_SIZE = 1 << BLOCK_BITS ) func BlockCount(fsize int64) int { return int((fsize + (BLOCK_SIZE - 1)) >> BLOCK_BITS) } func CalSha1(b []byte, r io.Reader) ([]byte, error) { h := sha1.New() _, err := io.Copy(h, r) if err != nil { return nil, err } return h.Sum(b), nil } func GetEtag(filename string) (etag string, err error) { f, err := os.Open(filename) if err != nil { return } defer f.Close() fi, err := f.Stat() if err != nil { return } fsize := fi.Size() blockCnt := BlockCount(fsize) sha1Buf := make([]byte, 0, 21) if blockCnt <= 1 { // file size <= 4M sha1Buf = append(sha1Buf, 0x16) sha1Buf, err = CalSha1(sha1Buf, f) if err != nil { return } } else { // file size > 4M sha1Buf = append(sha1Buf, 0x96) sha1BlockBuf := make([]byte, 0, blockCnt*20) for i := 0; i < blockCnt; i++ { body := io.LimitReader(f, BLOCK_SIZE) sha1BlockBuf, err = CalSha1(sha1BlockBuf, body) if err != nil { return } } sha1Buf, _ = CalSha1(sha1Buf, bytes.NewReader(sha1BlockBuf)) } etag = base64.URLEncoding.EncodeToString(sha1Buf) return } // func main() { // // if len(os.Args) < 2 { // fmt.Fprintln(os.Stderr, `Usage: qetag <filename>`) // return // } // etag, err := GetEtag(os.Args[1]) // if err != nil { // fmt.Fprintln(os.Stderr, err) // return // } // fmt.Println(etag) // }
有疑问加站长微信联系(非本文作者)