// Read the contents of the latest generation of the object with the supplied // name. func ReadObject( ctx context.Context, bucket gcs.Bucket, name string) (contents []byte, err error) { // Call the bucket. req := &gcs.ReadObjectRequest{ Name: name, } rc, err := bucket.NewReader(ctx, req) if err != nil { return } // Don't forget to close. defer func() { closeErr := rc.Close() if closeErr != nil && err == nil { err = fmt.Errorf("Close: %v", closeErr) } }() // Read the contents. contents, err = ioutil.ReadAll(rc) if err != nil { err = fmt.Errorf("ReadAll: %v", err) return } return }
func readOnce( ctx context.Context, o *gcs.Object, bucket gcs.Bucket) (r result, err error) { // Is the object large enough? if o.Size < *fSize { err = fmt.Errorf( "Object of size %d not large enough for read size %d", o.Size, *fSize) return } // Set up an appropriate request. req := &gcs.ReadObjectRequest{ Name: o.Name, Generation: o.Generation, Range: &gcs.ByteRange{}, } req.Range.Start = uint64(rand.Int63n(int64(o.Size - *fSize))) req.Range.Limit = req.Range.Start + *fSize // Create the reader. start := time.Now() rc, err := bucket.NewReader(ctx, req) if err != nil { err = fmt.Errorf("NewReader: %v", err) return } defer func() { closeErr := rc.Close() if err == nil && closeErr != nil { err = fmt.Errorf("Close: %v", closeErr) } }() // Measure the time to first byte. _, err = rc.Read([]byte{0}) if err != nil { err = fmt.Errorf("Read: %v", err) return } r.FirstByteLatency = time.Since(start) // And the time to read everything. n, err := io.Copy(ioutil.Discard, rc) if err != nil { err = fmt.Errorf("Copy: %v", err) return } r.FullBodyDuration = time.Since(start) r.BytesRead = int(n + 1) return }