in component/azstorage/block_blob.go [825:892]
func (bb *BlockBlob) ReadToFile(name string, offset int64, count int64, fi *os.File) (err error) {
log.Trace("BlockBlob::ReadToFile : name %s, offset : %d, count %d", name, offset, count)
//defer exectime.StatTimeCurrentBlock("BlockBlob::ReadToFile")()
blobClient := bb.Container.NewBlobClient(filepath.Join(bb.Config.prefixPath, name))
downloadPtr := to.Ptr(int64(1))
if common.MonitorBfs() {
bb.downloadOptions.Progress = func(bytesTransferred int64) {
trackDownload(name, bytesTransferred, count, downloadPtr)
}
}
defer log.TimeTrack(time.Now(), "BlockBlob::ReadToFile", name)
dlOpts := *bb.downloadOptions
dlOpts.Range = blob.HTTPRange{
Offset: offset,
Count: count,
}
_, err = blobClient.DownloadFile(context.Background(), fi, &dlOpts)
if err != nil {
e := storeBlobErrToErr(err)
if e == ErrFileNotFound {
return syscall.ENOENT
} else {
log.Err("BlockBlob::ReadToFile : Failed to download blob %s [%s]", name, err.Error())
return err
}
} else {
log.Debug("BlockBlob::ReadToFile : Download complete of blob %v", name)
// store total bytes downloaded so far
azStatsCollector.UpdateStats(stats_manager.Increment, bytesDownloaded, count)
}
if bb.Config.validateMD5 {
// Compute md5 of local file
fileMD5, err := common.GetMD5(fi)
if err != nil {
log.Warn("BlockBlob::ReadToFile : Failed to generate MD5 Sum for %s", name)
} else {
// Get latest properties from container to get the md5 of blob
prop, err := blobClient.GetProperties(context.Background(), &blob.GetPropertiesOptions{
CPKInfo: bb.blobCPKOpt,
})
if err != nil {
log.Warn("BlockBlob::ReadToFile : Failed to get properties of blob %s [%s]", name, err.Error())
} else {
blobMD5 := prop.ContentMD5
if blobMD5 == nil {
log.Warn("BlockBlob::ReadToFile : Failed to get MD5 Sum for blob %s", name)
} else {
// compare md5 and fail is not match
if !reflect.DeepEqual(fileMD5, blobMD5) {
log.Err("BlockBlob::ReadToFile : MD5 Sum mismatch %s", name)
return errors.New("md5 sum mismatch on download")
}
}
}
}
}
return nil
}