示例#1
0
        public override void ExecuteCmdlet()
        {
            if (AsJob.IsPresent)
            {
                DoBeginProcessing();
            }

            string   filePath  = this.Source;
            FileInfo localFile = new FileInfo(filePath);

            if (!localFile.Exists)
            {
                throw new FileNotFoundException(string.Format(CultureInfo.CurrentCulture, Resources.SourceFileNotFound, this.Source));
            }
            long fileSize = localFile.Length;

            // if FIPS policy is enabled, must use native MD5 for DMlib.
            if (fipsEnabled)
            {
                if (fileSize < sizeTB)
                {
                    CloudStorageAccount.UseV1MD5 = false;
                }
                else // use Track2 SDK
                {
                    WriteWarning("The uploaded file won't have Content MD5 hash, since caculate MD5 hash fail, most possiblly caused by FIPS is enabled on this machine.");
                }
            }

            bool isDirectory;

            string[] path = NamingUtil.ValidatePath(this.Path, out isDirectory);
            var      cloudFileToBeUploaded =
                BuildCloudFileInstanceFromPathAsync(localFile.Name, path, isDirectory).ConfigureAwait(false).GetAwaiter().GetResult();

            if (ShouldProcess(cloudFileToBeUploaded.Name, "Set file content"))
            {
                // Step 2: Build the CloudFile object which pointed to the
                // destination cloud file.
                this.RunTask(async taskId =>
                {
                    var progressRecord = new ProgressRecord(
                        this.OutputStream.GetProgressId(taskId),
                        string.Format(CultureInfo.CurrentCulture, Resources.SendAzureFileActivity, localFile.Name,
                                      cloudFileToBeUploaded.GetFullPath(), cloudFileToBeUploaded.Share.Name),
                        Resources.PrepareUploadingFile);

                    if (fileSize <= sizeTB)
                    {
                        await DataMovementTransferHelper.DoTransfer(() =>
                                                                    this.TransferManager.UploadAsync(
                                                                        localFile.FullName,
                                                                        cloudFileToBeUploaded,
                                                                        new UploadOptions
                        {
                            PreserveSMBAttributes = context is null ? false : context.PreserveSMBAttribute.IsPresent
                        },
                                                                        this.GetTransferContext(progressRecord, localFile.Length),
                                                                        this.CmdletCancellationToken),
                                                                    progressRecord,
                                                                    this.OutputStream).ConfigureAwait(false);
                    }
                    else // use Track2 SDK
                    {
                        //Create File
                        ShareFileClient fileClient = AzureStorageFile.GetTrack2FileClient(cloudFileToBeUploaded, Channel.StorageContext);

                        // confirm overwrite if file exist
                        if (!this.Force.IsPresent &&
                            fileClient.Exists(this.CmdletCancellationToken) &&
                            !await this.OutputStream.ConfirmAsync(string.Format(CultureInfo.CurrentCulture, Resources.OverwriteConfirmation, Util.ConvertToString(cloudFileToBeUploaded))))
                        {
                            return;
                        }

                        await fileClient.CreateAsync(fileSize, cancellationToken: this.CmdletCancellationToken).ConfigureAwait(false);

                        //Prepare progress Handler
                        IProgress <long> progressHandler = new Progress <long>((finishedBytes) =>
                        {
                            if (progressRecord != null)
                            {
                                // Size of the source file might be 0, when it is, directly treat the progress as 100 percent.
                                progressRecord.PercentComplete   = 0 == fileSize ? 100 : (int)(finishedBytes * 100 / fileSize);
                                progressRecord.StatusDescription = string.Format(CultureInfo.CurrentCulture, Resources.FileTransmitStatus, progressRecord.PercentComplete);
                                this.OutputStream.WriteProgress(progressRecord);
                            }
                        });

                        long blockSize = 4 * 1024 * 1024;
                        int maxWorkers = 4;

                        List <Task> runningTasks = new List <Task>();

                        IncrementalHash hash = null;
                        if (!fipsEnabled)
                        {
                            hash = IncrementalHash.CreateHash(HashAlgorithmName.MD5);
                        }

                        using (FileStream stream = File.OpenRead(localFile.FullName))
                        {
                            byte[] buffer      = null;
                            long lastBlockSize = 0;
                            for (long offset = 0; offset < fileSize; offset += blockSize)
                            {
                                long currentBlockSize = offset + blockSize < fileSize ? blockSize : fileSize - offset;

                                // Only need to create new buffer when chunk size change
                                if (currentBlockSize != lastBlockSize)
                                {
                                    buffer        = new byte[currentBlockSize];
                                    lastBlockSize = currentBlockSize;
                                }
                                await stream.ReadAsync(buffer: buffer, offset: 0, count: (int)currentBlockSize);
                                if (!fipsEnabled && hash != null)
                                {
                                    hash.AppendData(buffer);
                                }

                                Task task = UploadFileRangAsync(fileClient,
                                                                new HttpRange(offset, currentBlockSize),
                                                                new MemoryStream(buffer),
                                                                progressHandler);
                                runningTasks.Add(task);

                                // Check if any of upload range tasks are still busy
                                if (runningTasks.Count >= maxWorkers)
                                {
                                    await Task.WhenAny(runningTasks).ConfigureAwait(false);

                                    // Clear any completed blocks from the task list
                                    for (int i = 0; i < runningTasks.Count; i++)
                                    {
                                        Task runningTask = runningTasks[i];
                                        if (!runningTask.IsCompleted)
                                        {
                                            continue;
                                        }

                                        await runningTask.ConfigureAwait(false);
                                        runningTasks.RemoveAt(i);
                                        i--;
                                    }
                                }
                            }
                            // Wait for all upload range tasks finished
                            await Task.WhenAll(runningTasks).ConfigureAwait(false);
                        }

                        // Need set file properties
                        if ((!fipsEnabled && hash != null) || (context != null && context.PreserveSMBAttribute.IsPresent))
                        {
                            ShareFileHttpHeaders header = null;
                            if (!fipsEnabled && hash != null)
                            {
                                header             = new ShareFileHttpHeaders();
                                header.ContentHash = hash.GetHashAndReset();
                            }

                            FileSmbProperties smbProperties = null;
                            if (context != null && context.PreserveSMBAttribute.IsPresent)
                            {
                                FileInfo sourceFileInfo         = new FileInfo(localFile.FullName);
                                smbProperties                   = new FileSmbProperties();
                                smbProperties.FileCreatedOn     = sourceFileInfo.CreationTimeUtc;
                                smbProperties.FileLastWrittenOn = sourceFileInfo.LastWriteTimeUtc;
                                smbProperties.FileAttributes    = Util.LocalAttributesToAzureFileNtfsAttributes(File.GetAttributes(localFile.FullName));
                            }

                            // set file header and attributes to the file
                            fileClient.SetHttpHeaders(httpHeaders: header, smbProperties: smbProperties);
                        }

                        if (this.PassThru)
                        {
                            // fetch latest file properties for output
                            cloudFileToBeUploaded.FetchAttributes();
                        }
                    }

                    if (this.PassThru)
                    {
                        WriteCloudFileObject(taskId, this.Channel, cloudFileToBeUploaded);
                    }
                });
        /// <summary>
        /// Manage file properties
        /// </summary>
        /// <param name="shareServiceClient"></param>
        /// <returns></returns>
        private static async Task FilePropertiesSample(ShareServiceClient shareServiceClient)
        {
            Console.WriteLine();

            // Create the share name -- use a guid in the name so it's unique.
            string      shareName   = "demotest-" + Guid.NewGuid();
            ShareClient shareClient = shareServiceClient.GetShareClient(shareName);

            try
            {
                // Create share
                Console.WriteLine("Create Share");
                await shareClient.CreateIfNotExistsAsync();

                // Create directory
                Console.WriteLine("Create directory");
                ShareDirectoryClient rootDirectory = shareClient.GetRootDirectoryClient();

                ShareFileClient file = rootDirectory.GetFileClient("demofile");

                // Create file
                Console.WriteLine("Create file");
                await file.CreateAsync(1000);

                // Set file properties
                var headers = new ShareFileHttpHeaders
                {
                    ContentType     = "plain/text",
                    ContentEncoding = new string[] { "UTF-8" },
                    ContentLanguage = new string[] { "en" }
                };

                await file.SetHttpHeadersAsync(httpHeaders : headers);

                // Fetch file attributes
                ShareFileProperties shareFileProperties = await file.GetPropertiesAsync();

                Console.WriteLine("Get file properties:");
                Console.WriteLine("    Content type: {0}", shareFileProperties.ContentType);
                Console.WriteLine("    Content encoding: {0}", string.Join("", shareFileProperties.ContentEncoding));
                Console.WriteLine("    Content language: {0}", string.Join("", shareFileProperties.ContentLanguage));
                Console.WriteLine("    Length: {0}", shareFileProperties.ContentLength);
            }
            catch (RequestFailedException exRequest)
            {
                Common.WriteException(exRequest);
                Console.WriteLine(
                    "Please make sure your storage account is specified correctly in the app.config - then restart the sample.");
                Console.WriteLine("Press any key to exit");
                Console.ReadLine();
                throw;
            }
            catch (Exception ex)
            {
                Console.WriteLine("    Exception thrown creating share.");
                Common.WriteException(ex);
                throw;
            }
            finally
            {
                // Delete share
                Console.WriteLine("Delete share");
                await shareClient.DeleteIfExistsAsync();
            }

            Console.WriteLine();
        }