Upload All Files in Folder
Upload All Files in Folder
Sometimes an application might want to upload all files from a folder. To do so with the SDKs and the CLI requires traversing the folder tree, finding every file and uploading it accordingly.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Box.V2;
using Box.V2.Auth;
using Box.V2.Config;
using Box.V2.Converter;
using Box.V2.Exceptions;
using Box.V2.JWTAuth;
using Box.V2.Models;
using Newtonsoft.Json;
namespace BoxPlayground {
public class Program {
static void Main (string[] args) {
ExecuteMainAsync ().Wait ();
}
const long CHUNKED_UPLOAD_MINIMUM = 200000;
private static async Task ExecuteMainAsync () {
var directoryName = "dotnetUploadFolder";
var parentFolderId = "0";
var files = Directory.EnumerateFiles (directoryName);
using (FileStream fs = new FileStream ("./config.json", FileMode.Open)) {
var session = new BoxJWTAuth (BoxConfig.CreateFromJsonFile (fs));
var client = session.AdminClient (session.AdminToken ());
var folderId = "";
try {
var createdFolder = await client.FoldersManager.CreateAsync (
new BoxFolderRequest {
Parent = new BoxRequestEntity {
Id = parentFolderId
},
Name = directoryName
});
folderId = createdFolder.Id;
} catch (BoxConflictException<BoxFolder> e) {
folderId = e.ConflictingItems.FirstOrDefault ().Id;
System.Console.WriteLine ($"Found existing folder: {folderId}");
}
var fileUploadTasks = new List<Task<BoxFile>> ();
foreach (var file in files) {
fileUploadTasks.Add (Task.Run (
async () => {
System.Console.WriteLine (file);
var fileName = file.Split (Path.DirectorySeparatorChar)
.Where ((item) => { return item != directoryName; }).FirstOrDefault ();
System.Console.WriteLine (fileName);
var fileInfo = new FileInfo (file);
var preflightRequest = new BoxPreflightCheckRequest {
Name = fileName,
Size = fileInfo.Length,
Parent = new BoxRequestEntity {
Id = folderId
}
};
using (FileStream toUpload = new FileStream (file, FileMode.Open)) {
try {
var preflightCheck = await client.FilesManager.PreflightCheck (preflightRequest);
if (toUpload.Length < CHUNKED_UPLOAD_MINIMUM) {
using (SHA1 sha1 = SHA1.Create ()) {
var fileUploadRequest = new BoxFileRequest {
Name = fileName,
Parent = new BoxRequestEntity {
Id = folderId
}
};
var fileSHA = sha1.ComputeHash (toUpload);
System.Console.WriteLine (fileSHA);
return await client.FilesManager.UploadAsync (fileRequest: fileUploadRequest, stream: toUpload, contentMD5: fileSHA);
}
} else {
return await client.FilesManager.UploadUsingSessionAsync (stream: toUpload, fileName: fileName, folderId: folderId);
}
} catch (BoxPreflightCheckConflictException<BoxFile> e) {
if (toUpload.Length < CHUNKED_UPLOAD_MINIMUM) {
using (SHA1 sha1 = SHA1.Create ()) {
var fileSHA = sha1.ComputeHash (toUpload);
return await client.FilesManager.UploadNewVersionAsync (fileName: e.ConflictingItem.Name, fileId: e.ConflictingItem.Id, stream: toUpload, contentMD5: fileSHA);
}
} else {
await client.FilesManager.UploadFileVersionUsingSessionAsync (fileId: e.ConflictingItem.Id, stream: toUpload);
return await client.FilesManager.GetInformationAsync (e.ConflictingItem.Id);
}
}
}
}));
}
var uploaded = await Task.WhenAll (fileUploadTasks);
foreach (var file in uploaded) {
System.Console.WriteLine (file.Id);
}
}
}
}
}
Breakdown
The scripts above use the Box SDKs and the CLI to upload an entire folder. For the SDK scripts, they start by creating a directory in Box to match the local folder.
After the new directory is created, it uploads all files within the directory making sure to use all available Box features to make the uploads successful.
Using the Preflight API the files are checked for conflicts and size restrictions before they are uploaded. If a naming conflict is found, the script instead uploads a new version of that file.
Using the the SHA
hash of the file the scripts add a content-md5
header on
upload to make sure the file is successfully uploaded to Box without any bytes
lost or tampered with.
Finally, if a file size exceeds 20MB`, the script uses the Chunked Upload feature to make sure uploads are more reliable for larger files.