Skip to content

Instantly share code, notes, and snippets.

@allenmichael
Last active February 19, 2019 07:48
Show Gist options
  • Save allenmichael/5ba22d355a7f9693f487e7234bc15d0a to your computer and use it in GitHub Desktop.
Save allenmichael/5ba22d355a7f9693f487e7234bc15d0a to your computer and use it in GitHub Desktop.
Example for multiput upload in a simple Console Application
using System;
using System.IO;
using Box.V2;
using Box.V2.Config;
using Box.V2.JWTAuth;
namespace BoxPlayground
{
public static class BoxService
{
public static BoxClient GetBoxServiceAccountClient()
{
var session = new BoxJWTAuth(ConfigureBoxApi());
var adminToken = session.AdminToken();
return session.AdminClient(adminToken);
}
private static IBoxConfig ConfigureBoxApi()
{
IBoxConfig config = null;
// Change this to the config file for your Box App
using (FileStream fs = new FileStream(@"/Users/agrobelny/AM_DEV/dotnet/BoxPlayground/954218_rgprqmup_config.json", FileMode.Open))
{
config = BoxConfig.CreateFromJsonFile(fs);
}
return config;
}
public static int GetUploadPartsCount(long totalSize, long partSize)
{
if (partSize == 0)
throw new Exception("Part Size cannot be 0");
int numberOfParts = 1;
if (partSize != totalSize)
{
numberOfParts = Convert.ToInt32(totalSize / partSize);
numberOfParts += 1;
}
return numberOfParts;
}
public static Stream GetFilePart(Stream stream, long partSize, long partOffset)
{
// Default the buffer size to 4K.
const int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesRead = 0;
stream.Position = partOffset;
var partStream = new MemoryStream();
do
{
bytesRead = stream.Read(buffer, 0, 4096);
if (bytesRead > 0)
{
long bytesToWrite = bytesRead;
bool shouldBreak = false;
if (partStream.Length + bytesRead >= partSize)
{
bytesToWrite = partSize - partStream.Length;
shouldBreak = true;
}
partStream.Write(buffer, 0, Convert.ToInt32(bytesToWrite));
if (shouldBreak)
{
break;
}
}
} while (bytesRead > 0);
return partStream;
}
}
}
{
"boxAppSettings": {
"clientID": "",
"clientSecret": "",
"appAuth": {
"publicKeyID": "",
"privateKey": "",
"passphrase": ""
}
},
"webhooks": {
"primaryKey": "",
"secondaryKey": ""
},
"enterpriseID": ""
}

You'll need to change the code here to the file path for your own configuration file.

This is an example of how the configuration file should be formatted.

Here are some instructions on how to generate a configuration file.

If you're creating a new Box application, don't forget to authorize the application in your developer account, as outlined in these steps.

After you've obtained your configuration file, you'll need to change this line of code to the file path for your configuration file:

using (FileStream fs = new FileStream(@"/Users/agrobelny/AM_DEV/dotnet/BoxPlayground/954218_rgprqmup_config.json", FileMode.Open))

Here are some additional resources outlining how to utilize our Chunked Upload feature as well: The documentation on chunked upload The method in our .Net SDK

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Box.V2;
using Box.V2.Models;
namespace BoxPlayground
{
class Program
{
static void Main(string[] args)
{
try
{
ExecuteMainAsync().Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private static async Task ExecuteMainAsync()
{
var serviceAccount = BoxService.GetBoxServiceAccountClient();
var me = await serviceAccount.UsersManager.GetCurrentUserInformationAsync();
System.Console.WriteLine(me.Name);
System.Console.WriteLine(me.Id);
await ChunkedUpload(serviceAccount);
System.Console.WriteLine("Finished.");
}
private static async Task ChunkedUpload(BoxClient client)
{
long fileSize = 85000000;
System.Console.WriteLine("Retrieving randomized file...");
MemoryStream fileInMemoryStream = GetBigFileInMemoryStream(fileSize);
System.Console.WriteLine("File in memory.");
string remoteFileName = "UploadedUsingSession-" + DateTime.Now.TimeOfDay;
System.Console.WriteLine($"File name: {remoteFileName}");
string parentFolderId = "0";
var boxFileUploadSessionRequest = new BoxFileUploadSessionRequest()
{
FolderId = parentFolderId,
FileName = remoteFileName,
FileSize = fileSize
};
var boxFileUploadSession = await client.FilesManager.CreateUploadSessionAsync(boxFileUploadSessionRequest);
System.Console.WriteLine("Requested for an Upload Session...");
System.Console.WriteLine($"ID: {boxFileUploadSession.Id}");
System.Console.WriteLine($"Parts Processed: {boxFileUploadSession.NumPartsProcessed}");
System.Console.WriteLine($"Part Size: {boxFileUploadSession.PartSize}");
System.Console.WriteLine($"Abort: {boxFileUploadSession.SessionEndpoints.Abort}");
System.Console.WriteLine($"Commit: {boxFileUploadSession.SessionEndpoints.Commit}");
System.Console.WriteLine($"List Parts: {boxFileUploadSession.SessionEndpoints.ListParts}");
System.Console.WriteLine($"Log Event: {boxFileUploadSession.SessionEndpoints.LogEvent}");
System.Console.WriteLine($"Status: {boxFileUploadSession.SessionEndpoints.Status}");
System.Console.WriteLine($"Upload Part: {boxFileUploadSession.SessionEndpoints.UploadPart}");
System.Console.WriteLine($"Type: {boxFileUploadSession.Type}");
System.Console.WriteLine($"Total Parts: {boxFileUploadSession.TotalParts}");
System.Console.WriteLine($"Expires: {boxFileUploadSession.SessionExpiresAt}");
var boxSessionEndpoint = boxFileUploadSession.SessionEndpoints;
var uploadPartUri = new Uri(boxSessionEndpoint.UploadPart);
var commitUri = new Uri(boxSessionEndpoint.Commit);
var partSize = boxFileUploadSession.PartSize;
long partSizeLong;
long.TryParse(partSize, out partSizeLong);
var numberOfParts = BoxService.GetUploadPartsCount(fileSize, partSizeLong);
var boxSessionParts = await UploadPartsInSessionAsync(uploadPartUri, numberOfParts, partSizeLong, fileInMemoryStream, fileSize, client);
var allSessionParts = new List<BoxSessionPartInfo>();
foreach (var sessionPart in boxSessionParts)
{
System.Console.WriteLine($"Retrieved Session Part: {sessionPart.Part.PartId}");
allSessionParts.Add(sessionPart.Part);
}
BoxSessionParts sessionPartsForCommit = new BoxSessionParts() { Parts = allSessionParts };
// Commit
await client.FilesManager.CommitSessionAsync(commitUri, Box.V2.Utility.Helper.GetSha1Hash(fileInMemoryStream), sessionPartsForCommit);
// Delete file
string fileId = await GetFileId(parentFolderId, remoteFileName, client);
if (!string.IsNullOrWhiteSpace(fileId))
{
await client.FilesManager.DeleteAsync(fileId);
System.Console.WriteLine("Deleted");
}
}
private static MemoryStream GetBigFileInMemoryStream(long fileSize)
{
// Create random data to write to the file.
byte[] dataArray = new byte[fileSize];
new Random().NextBytes(dataArray);
MemoryStream memoryStream = new MemoryStream(dataArray);
return memoryStream;
}
private static async Task<List<BoxUploadPartResponse>> UploadPartsInSessionAsync(Uri uploadPartsUri, int numberOfParts, long partSize, Stream stream,
long fileSize, BoxClient client)
{
var tasks = Enumerable.Range(0, numberOfParts)
.Select(i =>
{
System.Console.WriteLine($"Current index: {i}");
// Split file as per part size
long partOffset = partSize * i;
Stream partFileStream = BoxService.GetFilePart(stream, partSize, partOffset);
string sha = Box.V2.Utility.Helper.GetSha1Hash(partFileStream);
partFileStream.Position = 0;
System.Console.WriteLine($"Running Task for {partOffset}...");
return client.FilesManager.UploadPartAsync(uploadPartsUri, sha, partOffset, fileSize, partFileStream);
});
List<BoxUploadPartResponse> allParts = (await Task.WhenAll(tasks)).ToList();
foreach (var resp in allParts)
{
System.Console.WriteLine($"Offset: {resp.Part.Offset}");
System.Console.WriteLine($"Part ID: {resp.Part.PartId}");
System.Console.WriteLine($"SHA: {resp.Part.Sha1}");
System.Console.WriteLine($"Size: {resp.Part.Size}");
}
return allParts;
}
private static async Task<string> GetFileId(string folderId, string fileName, BoxClient client)
{
BoxCollection<BoxItem> boxCollection = await client.FoldersManager.GetFolderItemsAsync(folderId, 1000);
return boxCollection.Entries.FirstOrDefault(item => item.Name == fileName)?.Id;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment