4.9. 创建 File

未匹配的标注

Github: github.com/bigfile/bigfile

创建 File

创建文件相对稍微复杂,我们给出一个完整的示例:

package main

import (
    "context"
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "io"
    "io/ioutil"
    "os"

    "github.com/bigfile/bigfile/databases/models"
    "github.com/bigfile/bigfile/rpc"
    "github.com/golang/protobuf/ptypes/wrappers"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
)

func createConnection() (*grpc.ClientConn, error) {
    var (
        err           error
        conn          *grpc.ClientConn
        cert          tls.Certificate
        certPool      *x509.CertPool
        rootCertBytes []byte
    )
    if cert, err = tls.LoadX509KeyPair("client.pem", "client.key"); err != nil {
        return nil, err
    }

    certPool = x509.NewCertPool()
    if rootCertBytes, err = ioutil.ReadFile("ca.pem"); err != nil {
        return nil, err
    }

    if !certPool.AppendCertsFromPEM(rootCertBytes) {
        return nil, err
    }

    if conn, err = grpc.Dial("192.168.0.103:10986", grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
        Certificates: []tls.Certificate{cert},
        RootCAs:      certPool,
    }))); err != nil {
        return nil, err
    }
    return conn, err
}

func main() {
    var (
        ctx            context.Context
        err            error
        resp           *rpc.FileCreateResponse
        cancel         context.CancelFunc
        client         rpc.FileCreateClient
        streamClient   rpc.FileCreate_FileCreateClient
        waitUploadFile *os.File
        conn           *grpc.ClientConn
    )

    if conn, err = createConnection(); err != nil {
        fmt.Println(err)
        return
    }
    defer conn.Close()
    ctx, cancel = context.WithCancel(context.Background())
    defer cancel()
    client = rpc.NewFileCreateClient(conn)
    if streamClient, err = client.FileCreate(ctx); err != nil {
        fmt.Println(err)
        return
    }
    if waitUploadFile, err = os.Open("/Users/fudenglong/Downloads/profile.jpeg"); err != nil {
        fmt.Println(err)
        return
    }
    defer waitUploadFile.Close()
    for index := 0; ; index++ {
        var chunk = make([]byte, models.ChunkSize*2)
        var size int
        var quit bool
        if size, err = waitUploadFile.Read(chunk); err != nil {
            if err != io.EOF {
                fmt.Println(err)
                return
            }
            quit = true
        }
        req := &rpc.FileCreateRequest{
            Token:   "ee3caab522b1848744c9df3aa980346f",
            Path:    "/my-profiles/profile.jpeg",
            Content: &wrappers.BytesValue{Value: chunk[:size]},
        }
        if index == 0 {
            req.Operation = &rpc.FileCreateRequest_Overwrite{Overwrite: true}
        } else {
            req.Operation = &rpc.FileCreateRequest_Append{Append: true}
        }
        fmt.Println("sending request")
        if err = streamClient.Send(req); err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println("waiting resp")
        if resp, err = streamClient.Recv(); err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println(resp)
        if quit {
            break
        }
    }
}

总结就是分片上传,在 RPC 服务中,我们没有对每次传输的字节大小做出限制,您可以根据情况适当调整,建议 1 MB 每次。这里有 FileCreateRequestFileCreateResponse 的类型声明以及 示例

英文文档:bigfile.site

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
Michael001
讨论数量: 0
发起讨论 只看当前版本


暂无话题~