use of com.qcloud.cos.exception.FileLockException in project cos-java-sdk-v5 by tencentyun.
the class TransferManager method doDownload.
/**
* Same as public interface, but adds a state listener so that callers can be notified of state
* changes to the download.
*
* @see TransferManager#download(GetObjectRequest, File)
*/
private Download doDownload(final GetObjectRequest getObjectRequest, final File file, final TransferStateChangeListener stateListener, final COSProgressListener cosProgressListener, final boolean resumeExistingDownload) {
appendSingleObjectUserAgent(getObjectRequest);
String description = "Downloading from " + getObjectRequest.getBucketName() + "/" + getObjectRequest.getKey();
TransferProgress transferProgress = new TransferProgress();
// COS progress listener to capture the persistable transfer when available
COSProgressListenerChain listenerChain = new COSProgressListenerChain(// The listener for updating transfer progress
new TransferProgressUpdatingListener(transferProgress), getObjectRequest.getGeneralProgressListener(), // Listeners
cosProgressListener);
// included in
// the original
// request
// The listener chain used by the low-level GetObject request.
// This listener chain ignores any COMPLETE event, so that we could
// delay firing the signal until the high-level download fully finishes.
getObjectRequest.setGeneralProgressListener(new ProgressListenerChain(new TransferCompletionFilter(), listenerChain));
long startingByte = 0;
long lastByte;
long[] range = getObjectRequest.getRange();
if (range != null && range.length == 2) {
startingByte = range[0];
lastByte = range[1];
} else {
GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest(getObjectRequest.getBucketName(), getObjectRequest.getKey());
if (getObjectRequest.getSSECustomerKey() != null)
getObjectMetadataRequest.setSSECustomerKey(getObjectRequest.getSSECustomerKey());
if (getObjectRequest.getVersionId() != null)
getObjectMetadataRequest.setVersionId(getObjectRequest.getVersionId());
final ObjectMetadata objectMetadata = cos.getObjectMetadata(getObjectMetadataRequest);
lastByte = objectMetadata.getContentLength() - 1;
}
final long origStartingByte = startingByte;
// We still pass the unfiltered listener chain into DownloadImpl
final DownloadImpl download = new DownloadImpl(description, transferProgress, listenerChain, null, stateListener, getObjectRequest, file);
long totalBytesToDownload = lastByte - startingByte + 1;
transferProgress.setTotalBytesToTransfer(totalBytesToDownload);
long fileLength = -1;
if (resumeExistingDownload) {
if (!FileLocks.lock(file)) {
throw new FileLockException("Fail to lock " + file + " for resume download");
}
try {
if (file.exists()) {
fileLength = file.length();
startingByte = startingByte + fileLength;
getObjectRequest.setRange(startingByte, lastByte);
transferProgress.updateProgress(Math.min(fileLength, totalBytesToDownload));
totalBytesToDownload = lastByte - startingByte + 1;
if (log.isDebugEnabled()) {
log.debug("Resume download: totalBytesToDownload=" + totalBytesToDownload + ", origStartingByte=" + origStartingByte + ", startingByte=" + startingByte + ", lastByte=" + lastByte + ", numberOfBytesRead=" + fileLength + ", file: " + file);
}
}
} finally {
FileLocks.unlock(file);
}
}
if (totalBytesToDownload < 0) {
throw new IllegalArgumentException("Unable to determine the range for download operation.");
}
final CountDownLatch latch = new CountDownLatch(1);
Future<?> future = threadPool.submit(new DownloadCallable(cos, latch, getObjectRequest, resumeExistingDownload, download, file, origStartingByte, fileLength));
download.setMonitor(new DownloadMonitor(download, future));
latch.countDown();
return download;
}
use of com.qcloud.cos.exception.FileLockException in project cos-java-sdk-v5 by tencentyun.
the class ServiceUtils method downloadToFile.
/**
* Same as {@link #downloadObjectToFile(COSObject, File, boolean, boolean)}
* but has an additional expected file length parameter for integrity
* checking purposes.
*
* @param expectedFileLength
* applicable only when appendData is true; the expected length
* of the file to append to.
*/
public static void downloadToFile(COSObject cosObject, final File dstfile, boolean performIntegrityCheck, final boolean appendData, final long expectedFileLength) {
// attempt to create the parent if it doesn't exist
File parentDirectory = dstfile.getParentFile();
if (parentDirectory != null && !parentDirectory.exists()) {
if (!(parentDirectory.mkdirs())) {
throw new CosClientException("Unable to create directory in the path" + parentDirectory.getAbsolutePath());
}
}
if (!FileLocks.lock(dstfile)) {
throw new FileLockException("Fail to lock " + dstfile + " for appendData=" + appendData);
}
OutputStream outputStream = null;
try {
final long actualLen = dstfile.length();
if (appendData && actualLen != expectedFileLength) {
// Fail fast to prevent data corruption
throw new IllegalStateException("Expected file length to append is " + expectedFileLength + " but actual length is " + actualLen + " for file " + dstfile);
}
outputStream = new BufferedOutputStream(new FileOutputStream(dstfile, appendData));
byte[] buffer = new byte[1024 * 10];
int bytesRead;
while ((bytesRead = cosObject.getObjectContent().read(buffer)) > -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
cosObject.getObjectContent().abort();
throw new CosClientException("Unable to store object contents to disk: " + e.getMessage(), e);
} finally {
IOUtils.closeQuietly(outputStream, log);
FileLocks.unlock(dstfile);
IOUtils.closeQuietly(cosObject.getObjectContent(), log);
}
if (performIntegrityCheck) {
byte[] clientSideHash = null;
byte[] serverSideHash = null;
try {
final ObjectMetadata metadata = cosObject.getObjectMetadata();
if (!skipMd5CheckStrategy.skipClientSideValidationPerGetResponse(metadata)) {
clientSideHash = Md5Utils.computeMD5Hash(dstfile);
serverSideHash = BinaryUtils.fromHex(metadata.getETag());
}
} catch (Exception e) {
log.warn("Unable to calculate MD5 hash to validate download: " + e.getMessage(), e);
}
if (clientSideHash != null && serverSideHash != null && !Arrays.equals(clientSideHash, serverSideHash)) {
throw new CosClientException("Unable to verify integrity of data download. " + "Client calculated content hash didn't match hash calculated by Qcloud COS. " + "The data stored in '" + dstfile.getAbsolutePath() + "' may be corrupt.");
}
}
}
Aggregations