private static void DownloadVHDFromCloud(Config config)
        {
            StorageCredentialsAccountAndKey creds =
                   new StorageCredentialsAccountAndKey(config.Account, config.Key);

            CloudBlobClient blobStorage = new CloudBlobClient(config.AccountUrl, creds);
            blobStorage.ReadAheadInBytes = 0;

            CloudBlobContainer container = blobStorage.GetContainerReference(config.Container);
            CloudPageBlob pageBlob = container.GetPageBlobReference(config.Blob);

            // Get the length of the blob
            pageBlob.FetchAttributes();
            long vhdLength = pageBlob.Properties.Length;
            long totalDownloaded = 0;
            Console.WriteLine("Vhd size:  " + Megabytes(vhdLength));

            // Create a new local file to write into
            FileStream fileStream = new FileStream(config.Vhd.FullName, FileMode.Create, FileAccess.Write);
            fileStream.SetLength(vhdLength);

            // Download the valid ranges of the blob, and write them to the file
            IEnumerable<PageRange> pageRanges = pageBlob.GetPageRanges();
            BlobStream blobStream = pageBlob.OpenRead();

            foreach (PageRange range in pageRanges)
            {
                // EndOffset is inclusive... so need to add 1
                int rangeSize = (int)(range.EndOffset + 1 - range.StartOffset);

                // Chop range into 4MB chucks, if needed
                for (int subOffset = 0; subOffset < rangeSize; subOffset += FourMegabyteAsBytes)
                {
                    int subRangeSize = Math.Min(rangeSize - subOffset, FourMegabyteAsBytes);
                    blobStream.Seek(range.StartOffset + subOffset, SeekOrigin.Begin);
                    fileStream.Seek(range.StartOffset + subOffset, SeekOrigin.Begin);

                    Console.WriteLine("Range: ~" + Megabytes(range.StartOffset + subOffset)
                                      + " + " + PrintSize(subRangeSize));
                    byte[] buffer = new byte[subRangeSize];

                    blobStream.Read(buffer, 0, subRangeSize);
                    fileStream.Write(buffer, 0, subRangeSize);
                    totalDownloaded += subRangeSize;
                }
            }
            Console.WriteLine("Downloaded " + Megabytes(totalDownloaded) + " of " + Megabytes(vhdLength));
        }
 public static Config Parse(string[] args)
 {
     if (args.Length != 3)
     {
         WriteConsoleAndExit("Usage: vhddownload <url> <file> <keyfile>");
     }
     Config config = new Config();
     config.Url = new Uri(args[0]);
     config.Vhd = new FileInfo(args[1]);
     if (config.Vhd.Exists)
     {
         try
         {
             config.Vhd.Delete();
         }
         catch (Exception e)
         {
             WriteConsoleAndExit("Failed to delete vhd file:\n" + e.ToString());
         }
     }
     config.ReadKey(args[2]);
     return config;
 }
Exemplo n.º 3
0
        private static void UploadVHDToCloud(Config config)
        {
            StorageCredentialsAccountAndKey creds = new
                   StorageCredentialsAccountAndKey(config.Account, config.Key);

            CloudBlobClient blobStorage = new CloudBlobClient(config.AccountUrl, creds);
            CloudBlobContainer container = blobStorage.GetContainerReference(config.Container);
            container.CreateIfNotExist();

            CloudPageBlob pageBlob = container.GetPageBlobReference(config.Blob);
            Console.WriteLine("Vhd size:  " + Megabytes(config.Vhd.Length));

            long blobSize = RoundUpToPageBlobSize(config.Vhd.Length);
            pageBlob.Create(blobSize);

            FileStream stream = new FileStream(config.Vhd.FullName, FileMode.Open, FileAccess.Read);
            BinaryReader reader = new BinaryReader(stream);

            long totalUploaded = 0;
            long vhdOffset = 0;
            int offsetToTransfer = -1;

            while (vhdOffset < config.Vhd.Length)
            {
                byte[] range = reader.ReadBytes(FourMegabytesAsBytes);

                int offsetInRange = 0;

                // Make sure end is page size aligned
                if ((range.Length % PageBlobPageSize) > 0)
                {
                    int grow = (int)(PageBlobPageSize - (range.Length % PageBlobPageSize));
                    Array.Resize(ref range, range.Length + grow);
                }

                // Upload groups of contiguous non-zero page blob pages.
                while (offsetInRange <= range.Length)
                {
                    if ((offsetInRange == range.Length) ||
                        IsAllZero(range, offsetInRange, PageBlobPageSize))
                    {
                        if (offsetToTransfer != -1)
                        {
                            // Transfer up to this point
                            int sizeToTransfer = offsetInRange - offsetToTransfer;
                            MemoryStream memoryStream = new MemoryStream(range,
                                         offsetToTransfer, sizeToTransfer, false, false);
                            pageBlob.WritePages(memoryStream, vhdOffset + offsetToTransfer);
                            Console.WriteLine("Range ~" + Megabytes(offsetToTransfer + vhdOffset)
                                    + " + " + PrintSize(sizeToTransfer));
                            totalUploaded += sizeToTransfer;
                            offsetToTransfer = -1;
                        }
                    }
                    else
                    {
                        if (offsetToTransfer == -1)
                        {
                            offsetToTransfer = offsetInRange;
                        }
                    }
                    offsetInRange += PageBlobPageSize;
                }
                vhdOffset += range.Length;
            }
            Console.WriteLine("Uploaded " + Megabytes(totalUploaded) + " of " + Megabytes(blobSize));
        }