2017-06-22 54 views
3

我试图从谷歌云存储(谷歌播放发布的应用程序的日志文件)下载一些文件。从谷歌云存储下载总是不正确的哈希

我的代码看起来像这样

Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "my-service-account-credential.json", EnvironmentVariableTarget.Process); 
StorageClient storageClient = StorageClient.Create(); 

var bucketName = "mybucketname"; 
var buckets = storageClient.GetBucket(bucketName); 
var objects = storageClient.ListObjects(bucketName).ToList(); 
foreach (var o in objects) 
{ 
    try 
    { 
     Directory.CreateDirectory(Path.GetDirectoryName(o.Name)); 
     using (var fs = File.Open(o.Name, FileMode.OpenOrCreate)) 
     { 
      await storageClient.DownloadObjectAsync(bucketName, o.Name, fs);            
     } 
    } 
    catch (Exception e) 
    { 
     if (e.Message.StartsWith("Incorrect hash")) 
     { 
      continue; 
     } 
     throw; 
    } 
} 

的代码实际上似乎很好地工作(通过查看实际下载的文件的内容来看,它是CSV文件)。但正如你所看到的,我已经实现了一个令人讨厌的尝试catch/hack,因为我下载的每个文件都会抛出一个异常,指出hash不正确。我假设客户端库将下载内容的散列值与存储区的散列值进行比较,并且这些散列值并不相同,导致它是一个例外。

唯一的例外是:

System.IO.IOException: Incorrect hash: expected 'DXpVGw==' (base64), was '2RMrcw==' (base64) 
    at Google.Cloud.Storage.V1.StorageClientImpl.<DownloadObjectAsyncImpl>d__48.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
    at MyClass.GoogleBucket.Functions.<DownloadGoogleBucketLogs>d__1.MoveNext() in mycode.cs:line 51 

所以我的问题是你如何下载对象,没有得到这个例外,显然一个是不应该做的我做了什么。

+0

您能否包含完整的例外详情? – mjwills

+0

我添加了异常详细信息,如果有帮助的话。请注意,我尝试了不同的时间,许多文件始终发生异常。 – sjkp

+0

我不知道这是否与客户端库有关。您能否根据他们的GCS元数据告诉我对象的内容类型和内容编码? –

回答

6

TL; DR:更新到2.1.0。 (或者,如果你绝望,那么在此之前取回并建立源代码。)

这是一个棘手的问题。

问题是HttpClient在运行中自动解压缩数据,但服务器提供的散列是用于压缩内容的。

我们现在对REST API支持库和Google.Cloud.Storage.V1库进行了更改,以便在解压缩之前拦截并散列下载的数据。这些变化在Github中合并,并将在2.1.0版本发布,我预计将在1月初发布。

请注意,这不会修复客户端解压缩被禁用的单独边角情况,导致服务器端解压缩,但仍然使用压缩内容的散列。我们是tracking that separately,但它不会影响这里的示例代码,因为如果您在初始化程序中创建了StorageService明确禁用的gzip支持,然后创建了StorageClient以包装该服务,您只能看到它。