环境:
Java客户端(“google-api-services-storage”,“v1-rev33-1.20.0”)使用JSON API(com.google.api.services.storage.Storage类)。
目标:
使用Java客户端将大对象从“标准”移动到“近线”桶(文件大小为512 MB)。
步骤:
使用"rewrite" API方法。
问题:
我在20秒内收到SocketTimeoutException。
调查:
当我使用从“标准”存储桶重写到同一对象的另一个“标准”存储桶时,相同的代码工作正常
我还尝试了APIs Explorer并创建了一个请求,将对象从“标准”重写为“近线”桶。服务器在大约27秒内响应,响应中的“totalBytesRewritten”属性大约是文件大小的一半。如何获得和处理这种反应?
文件说:
“如果源和目标是不同的位置和/或存储类,则重写方法可能需要多次调用。”
我的代码(Java):
final Storage.Objects.Rewrite rewriteRequest = storage.objects().rewrite(
STANDARD_BUCKET_NAME,
SOURCE_OBJECT_PATH,
NEARLINE_BUCKET_NAME,
TARGET_OBJECT_PATH,
null // no metadata overriding
);
rewriteRequest.execute();
请帮忙。
答案 0 :(得分:0)
根据documentation,如果文件被拆分为块,则应该使用重写的第一个响应中返回的'rewriteToken'再次调用rewrite。操作将恢复,再处理一大块数据。这应该重复,直到响应有getDone()== true。
我对java api的实现:
private void rewriteUntilDone(final String sourceBucket, final String sourceKey,
final String destBucket, final String destKey) throws IOException {
rewriteUntilDone(sourceBucket, sourceKey, destBucket, destKey, null);
}
private void rewriteUntilDone(final String sourceBucket, final String sourceKey,
final String destBucket, final String destKey,
@Nullable final String rewriteToken)
throws IOException {
Storage.Objects.Rewrite rewrite = googleStorage.objects().rewrite(sourceBucket, sourceKey, destBucket, destKey, null);
if (rewriteToken != null) {
rewrite.setRewriteToken(rewriteToken);
}
RewriteResponse rewriteResponse = rewrite.execute();
if (!rewriteResponse.getDone()) {
String rewriteToken2 = rewriteResponse.getRewriteToken();
BigInteger totalBytesRewritten = rewriteResponse.getTotalBytesRewritten();
log.debug("Rewriting not finished, bytes completed: {}. Calling rewrite again with token {}", totalBytesRewritten, rewriteToken2);
rewriteUntilDone(sourceBucket, sourceKey, destBucket, destKey, rewriteToken2);
}
}
编辑: 此外,您可能必须增加读取超时。似乎重写在27秒后响应,但默认的时间是20秒。 Wrap your GoogleCredentials to set the read timeout