0

What is the best way to download files, specifically large files? I was looking at using REST which I use for SharePoint Online but not sure on how to do the authentication for SharePoint On Premise. I came across this thread Problem with OpenBinaryStream (CSOM) with large files so not sure if CSOM is the best approach.

Any advice or pointers is much appreciated.

2
  • How big is the file you are trying to download? Oct 20 '16 at 20:54
  • At the moment I don't have a test case.i guess I need to be able to download the up most limit of sharepoint
    – Webfort
    Oct 20 '16 at 20:57
0

I've written this helper class for CSOM authentication. It works for both SPOnline and onpremises:

    public class ContextHelper
{
    public static ClientContext GetClientContext(string siteUrl, string user)
    {
        SecureString securePassword = PasswordHelper.GetPasswordFromConsoleInput();
        return GetClientContext(siteUrl, user, securePassword);
    }
    public static ClientContext GetClientContext(string siteUrl, string user, string password)
    {
        SecureString securePassword = StringExtentions.GetSecureString(password);
        return GetClientContext(siteUrl, user, securePassword);
  }
    public static ClientContext GetClientContext(string siteUrl, string user, SecureString password)
    {
        bool onPrem = true;

        if (siteUrl.Contains("sharepoint.com"))
        {
            onPrem = false;
        }

        Console.WriteLine();
        Console.WriteLine("Current domain: {0}", Environment.UserDomainName);

        ClientContext clientContext = new ClientContext(siteUrl);
        clientContext.AuthenticationMode = ClientAuthenticationMode.Default;

        if (onPrem)
        {
            clientContext.Credentials = new NetworkCredential(user, password);
        }
        else
        {
            clientContext.Credentials = new SharePointOnlineCredentials(user, password);
        }

        clientContext.Load(clientContext.Web);
        clientContext.ExecuteQuery();
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine("Connected to the site: {0} | {1}", clientContext.Web.Title, siteUrl);
        Console.ForegroundColor = ConsoleColor.White ;

        return clientContext;
    }

}

Usage:

ClientContext clientContext = ContextHelper.GetClientContext("https://contoso.sharepoint.com/site/subsite/", @"dmolodtsov@contoso.com");

And this is the helper class for downloading the entire libraries via CSOM:

    public class FileHelper
{
    public static void DownloadLibrary(ClientContext clientContext, string LibraryTitle, string destinationFolder)
    {
        var web = clientContext.Web;
        clientContext.Load(web);
        clientContext.ExecuteQuery();
        List list = web.Lists.GetByTitle(LibraryTitle);
        clientContext.Load(list);
        clientContext.ExecuteQuery();
        clientContext.Load(list.RootFolder);
        clientContext.ExecuteQuery();
        clientContext.Load(list.RootFolder.Folders);
        clientContext.ExecuteQuery();
        DownloadFilesFromFolder(clientContext, list.RootFolder, destinationFolder);
    }

    public static void DownloadFilesFromFolder(ClientContext clientContext, Folder folder, string destinationFolder)
    {
        string siteUrl = (new Uri(clientContext.Web.Url)).PathAndQuery;
        string localDestinationFolder = destinationFolder + "/" + folder.ServerRelativeUrl.Replace(siteUrl, string.Empty);
        localDestinationFolder = (new Uri(localDestinationFolder)).LocalPath;
        if (!Directory.Exists(localDestinationFolder))
        {
            Directory.CreateDirectory(localDestinationFolder);
            Console.WriteLine("Created Folder: {0}", localDestinationFolder);
        }

        clientContext.Load(folder.Files);
        clientContext.ExecuteQuery();
        foreach (Microsoft.SharePoint.Client.File file in folder.Files)
        {
        Stream fs = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, file.ServerRelativeUrl).Stream;
            byte[] binary = getByteArray(fs);
            string destinationFileName = localDestinationFolder + "/" + file.Name;
        FileStream stream = new FileStream(destinationFileName, FileMode.Create);
            BinaryWriter writer = new BinaryWriter(stream);
            writer.Write(binary);
            writer.Close();

            Console.WriteLine("Downloaded file: {0}", destinationFileName);
        }
        clientContext.Load(folder.Folders);
        clientContext.ExecuteQuery();
        foreach (Folder subFolder in folder.Folders)
        {
            DownloadFilesFromFolder(clientContext, subFolder, destinationFolder);
        }
    }

    public static byte[] getByteArray(Stream input)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }

}

Usage:

 FileHelper.DownloadLibrary(clientContext, "Assets", "C:\results");
0

I have developed a tool (proprietary) that uses XmlHttpRequest to download files. The html file with the JavaScript code is placed in SharePoint so it caters automatically for authentication tokens. It works fine even for large files such as 10 GB. This may provide an alternative for CSOM or REST.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.