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
每次。这里有 FileCreateRequest 和 FileCreateResponse 的类型声明以及 示例。
英文文档:bigfile.site
推荐文章: