Skip to content

Commit 1336fc1

Browse files
author
seguler
committed
Init the repo
0 parents  commit 1336fc1

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

PutBlockFromURL.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 15
4+
VisualStudioVersion = 15.0.27428.2027
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PutBlockFromURL", "PutBlockFromURL\PutBlockFromURL.csproj", "{63C74E51-DC3A-429A-BB49-84E4BCD984D1}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{63C74E51-DC3A-429A-BB49-84E4BCD984D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{63C74E51-DC3A-429A-BB49-84E4BCD984D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{63C74E51-DC3A-429A-BB49-84E4BCD984D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{63C74E51-DC3A-429A-BB49-84E4BCD984D1}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {9D07C8FE-150F-4B01-8593-573693B12831}
24+
EndGlobalSection
25+
EndGlobal

PutBlockFromURL/Program.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using Microsoft.WindowsAzure.Storage;
2+
using Microsoft.WindowsAzure.Storage.Blob;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Diagnostics;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
namespace PutBlockFromURL
10+
{
11+
class Program
12+
{
13+
static String account1_connectionstring = "<add your connection string for the source account>";
14+
static String account2_connectionstring = "<add your connection string for the dest account>";
15+
static String container = "mycontainer";
16+
static String blob = "myfile";
17+
18+
static void Main(string[] args) {
19+
// Time the copy operation
20+
Stopwatch stopWatch = new Stopwatch();
21+
stopWatch.Start();
22+
23+
// MainAsync is the static method that calls async Storage APIs
24+
MainAsync(args).GetAwaiter().GetResult();
25+
26+
// Stop the watch and print
27+
stopWatch.Stop();
28+
Console.WriteLine("Finished the copy in " + stopWatch.Elapsed);
29+
30+
Console.WriteLine("Hit any key to exit ");
31+
Console.ReadKey();
32+
33+
}
34+
static async Task MainAsync(string[] args)
35+
{
36+
// Copy a blob from account1 to account2 using Put Block From URL
37+
CloudStorageAccount account1 = CloudStorageAccount.Parse(account1_connectionstring);
38+
CloudStorageAccount account2 = CloudStorageAccount.Parse(account2_connectionstring);
39+
CloudBlobClient client1 = account1.CreateCloudBlobClient();
40+
CloudBlobClient client2 = account2.CreateCloudBlobClient();
41+
42+
CloudBlobContainer container1 = client1.GetContainerReference(container);
43+
CloudBlobContainer container2 = client2.GetContainerReference(container);
44+
45+
// Generate a read only SAS token valid for 1 hour
46+
// This will be used as a source for Put Block From URL
47+
// Append the SAS token to the source
48+
CloudBlockBlob blob1 = container1.GetBlockBlobReference(blob);
49+
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
50+
policy.SharedAccessExpiryTime = DateTime.Now.AddHours(1);
51+
policy.SharedAccessStartTime = DateTime.Now.AddSeconds(-10);
52+
policy.Permissions = SharedAccessBlobPermissions.Read;
53+
String SAS = blob1.GetSharedAccessSignature(policy);
54+
String full_uri = blob1.Uri.ToString() + SAS;
55+
56+
// Get a reference to the destination blob
57+
CloudBlockBlob blob2 = container2.GetBlockBlobReference(blob+"_destination");
58+
59+
// Get Blob Properties to find out the length of the source blob
60+
await blob1.FetchAttributesAsync();
61+
62+
// Based on 100MB blocks, let's figure out the number of blocks required to copy the data
63+
// We will call (blocks) times the PutBlockFromURL API
64+
int block_size = 100 * 1024 * 1024;
65+
long blocks = (blob1.Properties.Length + block_size - 1 )/ block_size;
66+
67+
try
68+
{
69+
// Get a block id List
70+
List<string> destBlockList = GetBlockIdList((int)blocks);
71+
72+
// Call PutBlock multiple times
73+
// Alternatively do not await, and add all calls into a List<Task>() and then call WhenAll to concurrently copy all
74+
for (int i = 0; i < blocks; i++)
75+
{
76+
Console.WriteLine("Putting block " + i + " with offset " + (long)i * (long)block_size);
77+
await blob2.PutBlockAsync(destBlockList[i], new Uri(full_uri), (long)i * (long)block_size, block_size, null);
78+
}
79+
80+
// Let's now PutBlockList to commit all Blocks in the destBlockList
81+
await blob2.PutBlockListAsync(destBlockList);
82+
}
83+
catch (StorageException ex) {
84+
Console.WriteLine(ex.RequestInformation.HttpStatusCode);
85+
Console.WriteLine(ex.Message);
86+
}
87+
88+
}
89+
90+
public static List<string> GetBlockIdList(int count)
91+
{
92+
List<string> blocks = new List<string>();
93+
for (int i = 0; i < count; i++)
94+
{
95+
blocks.Add(Convert.ToBase64String(Guid.NewGuid().ToByteArray()));
96+
}
97+
return blocks;
98+
}
99+
}
100+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.0</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="WindowsAzure.Storage" Version="9.3.0" />
10+
</ItemGroup>
11+
12+
</Project>

0 commit comments

Comments
 (0)