public static string CalulateHash_MD5(Stream stream, long skipBytes, long size) { string md5 = null; if (stream is FileStream) { using (MD5 md5Hash = MD5.Create()) using (var md5stream = new PartialFileStream(((FileStream)stream).Name, FileMode.Open, FileAccess.Read, FileShare.Read, skipBytes, size)) { md5 = Convert.ToBase64String(md5Hash.ComputeHash(md5stream)); } } else { using (MD5 md5Hash = MD5.Create()) using (var md5stream = new PartialStream(stream, skipBytes, size)) { md5 = Convert.ToBase64String(md5Hash.ComputeHash(md5stream)); } } return(md5); }
public static AppendUploadResult AppendUpload ( IOssClientBuilder clientBuilder, string bucketName, string objectName, Stream streamToUpload, Action <AppendUploadOptions> options = null, EventHandler <StreamTransferProgressArgs> streamTransferProgress = null, CancellationToken cancellationToken = default(CancellationToken) ) { if (clientBuilder == null) { throw new ArgumentNullException(nameof(clientBuilder)); } if (streamToUpload == null) { throw new ArgumentNullException(nameof(streamToUpload)); } AppendUploadOptions uploadOptions = new AppendUploadOptions(); options?.Invoke(uploadOptions); int blockSize = Math.Max(MIN_BLOCK_SIZE, uploadOptions.InitialBlockSize); var client = clientBuilder.Build(o => o.EnableCrcCheck = true); long position = 0; ObjectMetadata metadata = null; try { metadata = client.GetObjectMetadata(bucketName, objectName); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception) #pragma warning restore CA1031 // Do not catch general exception types { // No such object } if (metadata != null) { if (string.Compare(metadata.ObjectType, "Appendable", StringComparison.InvariantCultureIgnoreCase) == 0) { if (metadata.ContentLength > 0) { if (metadata.ContentLength <= streamToUpload.Length) { if (uploadOptions.AllowResume) { position = metadata.ContentLength; if (uploadOptions.VerifyBeforeResume) { using (var stream = new PartialStream(streamToUpload, 0, position)) using (var crc64 = new Crc64HashAlgorithm()) { crc64.ComputeHash(stream); string localHash = BitConverter.ToUInt64(crc64.Hash, 0).ToString(CultureInfo.InvariantCulture); if (string.Compare(metadata.Crc64, localHash, StringComparison.InvariantCultureIgnoreCase) != 0) { if (uploadOptions.AllowOverwrite) { client.DeleteObject(bucketName, objectName); position = 0; } else { throw new OssException("Hash mismatched, could not resume file"); } } } } } else if (uploadOptions.AllowOverwrite) { client.DeleteObject(bucketName, objectName); } else { throw new OssException("Could not resume or overwrite file"); } } else { if (uploadOptions.AllowOverwrite) { client.DeleteObject(bucketName, objectName); } else { throw new OssException("Could not resume, the length of remote object is longer than local object."); } } } } else if (uploadOptions.AllowOverwrite) { client.DeleteObject(bucketName, objectName); } else { throw new OssException("The object is not appendable"); } } if (streamToUpload.Length == position) { return(new AppendUploadResult { ETag = metadata.ETag, Crc64 = metadata.Crc64, ContentLength = metadata.ContentLength }); } while (true) { var result = Retry((retryCount) => { if (retryCount > 0) { blockSize = Math.Max(MIN_BLOCK_SIZE, blockSize >> 1); } var length = Math.Min(blockSize, streamToUpload.Length - position); var request = new AppendObjectRequest(bucketName, objectName) { Content = new PartialStream(streamToUpload, position, length), Position = position, StreamTransferProgress = (s, e) => { cancellationToken.ThrowIfCancellationRequested(); if (streamTransferProgress != null) { streamTransferProgress.Invoke(s, new StreamTransferProgressArgs(e.IncrementTransferred, position + e.TransferredBytes, streamToUpload.Length)); } } }; return(client.AppendObject(request)); }, cancellationToken: cancellationToken); position = result.NextAppendPosition; if (position >= streamToUpload.Length) { return(new AppendUploadResult { ETag = result.ETag, Crc64 = result.HashCrc64Ecma.ToString(CultureInfo.InvariantCulture), ContentLength = result.NextAppendPosition, AppendObjectResult = result }); } } }