【问题标题】:C# Sharepoint upload large file into subfolderC# Sharepoint 将大文件上传到子文件夹
【发布时间】:2020-01-22 19:52:27
【问题描述】:

我在尝试将大文件上传到子共享点文件夹时遇到问题。 该问题与变量libraryName 有关。我不确定我是否可以更改此设置,以便我可以使用 url。

示例: var site = ""https://sharepoint.com/sites/Test_Site1/"

var relative = "文档/Folder1/folder2/

https://docs.microsoft.com/en-us/sharepoint/dev/solution-guidance/upload-large-files-sample-app-for-sharepoint

public Microsoft.SharePoint.Client.File UploadFileSlicePerSlice(ClientContext ctx, string libraryName, string fileName, int fileChunkSizeInMB = 3)
{
  // Each sliced upload requires a unique ID.
  Guid uploadId = Guid.NewGuid();

  // Get the name of the file.
  string uniqueFileName = Path.GetFileName(fileName);

  // Ensure that target library exists, and create it if it is missing.
  if (!LibraryExists(ctx, ctx.Web, libraryName))
  {
    CreateLibrary(ctx, ctx.Web, libraryName);
  }
  // Get the folder to upload into.
  List docs = ctx.Web.Lists.GetByTitle(libraryName);
  ctx.Load(docs, l => l.RootFolder);
  // Get the information about the folder that will hold the file.
  ctx.Load(docs.RootFolder, f => f.ServerRelativeUrl);
  ctx.ExecuteQuery();

  // File object.
  Microsoft.SharePoint.Client.File uploadFile = null;

  // Calculate block size in bytes.
  int blockSize = fileChunkSizeInMB * 1024 * 1024;

  // Get the information about the folder that will hold the file.
  ctx.Load(docs.RootFolder, f => f.ServerRelativeUrl);
  ctx.ExecuteQuery();


  // Get the size of the file.
  long fileSize = new FileInfo(fileName).Length;

  if (fileSize <= blockSize)
  {
    // Use regular approach.
    using (FileStream fs = new FileStream(fileName, FileMode.Open))
    {
      FileCreationInformation fileInfo = new FileCreationInformation();
      fileInfo.ContentStream = fs;
      fileInfo.Url = uniqueFileName;
      fileInfo.Overwrite = true;
      uploadFile = docs.RootFolder.Files.Add(fileInfo);
      ctx.Load(uploadFile);
      ctx.ExecuteQuery();
      // Return the file object for the uploaded file.
      return uploadFile;
    }
  }
  else
  {
    // Use large file upload approach.
    ClientResult<long> bytesUploaded = null;

    FileStream fs = null;
    try
    {
      fs = System.IO.File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
      using (BinaryReader br = new BinaryReader(fs))
      {
        byte[] buffer = new byte[blockSize];
        Byte[] lastBuffer = null;
        long fileoffset = 0;
        long totalBytesRead = 0;
        int bytesRead;
        bool first = true;
        bool last = false;

        // Read data from file system in blocks.
        while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
        {
          totalBytesRead = totalBytesRead + bytesRead;

          // You've reached the end of the file.
          if (totalBytesRead == fileSize)
          {
            last = true;
            // Copy to a new buffer that has the correct size.
            lastBuffer = new byte[bytesRead];
            Array.Copy(buffer, 0, lastBuffer, 0, bytesRead);
          }

          if (first)
          {
            using (MemoryStream contentStream = new MemoryStream())
            {
              // Add an empty file.
              FileCreationInformation fileInfo = new FileCreationInformation();
              fileInfo.ContentStream = contentStream;
              fileInfo.Url = uniqueFileName;
              fileInfo.Overwrite = true;
              uploadFile = docs.RootFolder.Files.Add(fileInfo);

              // Start upload by uploading the first slice.
              using (MemoryStream s = new MemoryStream(buffer))
              {
                // Call the start upload method on the first slice.
                bytesUploaded = uploadFile.StartUpload(uploadId, s);
                ctx.ExecuteQuery();
                // fileoffset is the pointer where the next slice will be added.
                fileoffset = bytesUploaded.Value;
              }

              // You can only start the upload once.
              first = false;
            }
          }
          else
          {
            if (last)
            {
              // Is this the last slice of data?
              using (MemoryStream s = new MemoryStream(lastBuffer))
              {
                // End sliced upload by calling FinishUpload.
                uploadFile = uploadFile.FinishUpload(uploadId, fileoffset, s);
                ctx.ExecuteQuery();

                // Return the file object for the uploaded file.
                return uploadFile;
              }
            }
            else
            {
              using (MemoryStream s = new MemoryStream(buffer))
              {
                // Continue sliced upload.
                bytesUploaded = uploadFile.ContinueUpload(uploadId, fileoffset, s);
                ctx.ExecuteQuery();
                // Update fileoffset for the next slice.
                fileoffset = bytesUploaded.Value;
              }
            }
          }
        } // while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
      }
    }
    finally
    {
      if (fs != null)
      {
        fs.Dispose();
      }
    }
  }

  return null;
}

这是我运行该方法的第一页

using Microsoft.SharePoint.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security;
using System.Text;
using System.Threading.Tasks;

namespace Contoso.Core.LargeFileUpload
{
    class Program
    {
        static void Main(string[] args)
        {
            // Request Office365 site from the user
            string siteUrl = @"https://bundegruppen.sharepoint.com/sites/F24-2905/";

            /* Prompt for Credentials */
            //Console.WriteLine("Filer blir overført til site: {0}", siteUrl);
            string userName = "xx.xx@bxxbygg.no";
            SecureString pwd = new SecureString();
            string password = "xxx";
            foreach (char c in password.ToCharArray()) pwd.AppendChar(c);

            /* End Program if no Credentials */
            if (string.IsNullOrEmpty(userName) || (pwd == null))
                return;

            ClientContext ctx = new ClientContext(siteUrl);
            ctx.AuthenticationMode = ClientAuthenticationMode.Default;
            ctx.Credentials = new SharePointOnlineCredentials(userName, pwd);


            // These should both work as expected.
            try
            {
                // Alternative 3 for uploading large files: slice per slice which allows you to stop and resume a download
                new FileUploadService().UploadFileSlicePerSliceToFolder(ctx, "Dokumenter/General", @"C:\Temp\F24_Sammenstillingsmodell.smc");
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Exception while uploading files to the target site: {0}.", ex.ToString()));
                Console.WriteLine("Press enter to continue.");
                Console.Read();
            }
            // Just to see what we have in console
            Console.ForegroundColor = ConsoleColor.White;
        }


    }

}

【问题讨论】:

  • 您收到的错误信息是什么?
  • 将文件上传到目标站点时出现异常:Microsoft.SharePoint.Client.ServerException:URL 地址中不存在 List Dokumenter/General
  • 我也在尝试设置 libaryName = Dokumenter/General List docs = ctx.Web.Lists.GetByTitle(libraryName);当我只写“Dokumenter”时它可以工作。但我想要子文件夹中的文件
  • 你为 libraryName 传递了什么值?你在传递“Documents/Folder1/folder2/”吗?
  • 我想要做的就是上传一个大文件到一个特定的共享点文件夹。如果有人有另一种方式更短的代码我会为那哈哈。

标签: c# sharepoint


【解决方案1】:

您编写的代码只是为了将指定文件上传到命名库的根文件夹。如果您传递文件夹的完整路径而不仅仅是库名称,它将失败。
以下是该函数的修改版本,它应该允许您将完整的 serverRelativeUrl 传递到所需的文件夹:

public Microsoft.SharePoint.Client.File UploadFileSlicePerSliceToFolder(ClientContext ctx, string serverRelativeFolderUrl, string fileName, int fileChunkSizeInMB = 3)
{
  // Each sliced upload requires a unique ID.
  Guid uploadId = Guid.NewGuid();

  // Get the name of the file.
  string uniqueFileName = Path.GetFileName(fileName);

  // Get the folder to upload into.
  Folder uploadFolder = ctx.web.GetFolderByServerRelativeUrl(serverRelativeFolderUrl);

  // Get the information about the folder that will hold the file.
  ctx.Load(uploadFolder);
  ctx.ExecuteQuery();

  // File object.
  Microsoft.SharePoint.Client.File uploadFile = null;

  // Calculate block size in bytes.
  int blockSize = fileChunkSizeInMB * 1024 * 1024;

  // Get the information about the folder that will hold the file.
  ctx.Load(uploadFolder, f => f.ServerRelativeUrl);
  ctx.ExecuteQuery();


  // Get the size of the file.
  long fileSize = new FileInfo(fileName).Length;

  if (fileSize <= blockSize)
  {
    // Use regular approach.
    using (FileStream fs = new FileStream(fileName, FileMode.Open))
    {
      FileCreationInformation fileInfo = new FileCreationInformation();
      fileInfo.ContentStream = fs;
      fileInfo.Url = uniqueFileName;
      fileInfo.Overwrite = true;
      uploadFile = uploadFolder.Files.Add(fileInfo);
      ctx.Load(uploadFile);
      ctx.ExecuteQuery();
      // Return the file object for the uploaded file.
      return uploadFile;
    }
  }
  else
  {
    // Use large file upload approach.
    ClientResult<long> bytesUploaded = null;

    FileStream fs = null;
    try
    {
      fs = System.IO.File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
      using (BinaryReader br = new BinaryReader(fs))
      {
        byte[] buffer = new byte[blockSize];
        Byte[] lastBuffer = null;
        long fileoffset = 0;
        long totalBytesRead = 0;
        int bytesRead;
        bool first = true;
        bool last = false;

        // Read data from file system in blocks.
        while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
        {
          totalBytesRead = totalBytesRead + bytesRead;

          // You've reached the end of the file.
          if (totalBytesRead == fileSize)
          {
            last = true;
            // Copy to a new buffer that has the correct size.
            lastBuffer = new byte[bytesRead];
            Array.Copy(buffer, 0, lastBuffer, 0, bytesRead);
          }

          if (first)
          {
            using (MemoryStream contentStream = new MemoryStream())
            {
              // Add an empty file.
              FileCreationInformation fileInfo = new FileCreationInformation();
              fileInfo.ContentStream = contentStream;
              fileInfo.Url = uniqueFileName;
              fileInfo.Overwrite = true;
              uploadFile = uploadFolder.Files.Add(fileInfo);

              // Start upload by uploading the first slice.
              using (MemoryStream s = new MemoryStream(buffer))
              {
                // Call the start upload method on the first slice.
                bytesUploaded = uploadFile.StartUpload(uploadId, s);
                ctx.ExecuteQuery();
                // fileoffset is the pointer where the next slice will be added.
                fileoffset = bytesUploaded.Value;
              }

              // You can only start the upload once.
              first = false;
            }
          }
          else
          {
            if (last)
            {
              // Is this the last slice of data?
              using (MemoryStream s = new MemoryStream(lastBuffer))
              {
                // End sliced upload by calling FinishUpload.
                uploadFile = uploadFile.FinishUpload(uploadId, fileoffset, s);
                ctx.ExecuteQuery();

                // Return the file object for the uploaded file.
                return uploadFile;
              }
            }
            else
            {
              using (MemoryStream s = new MemoryStream(buffer))
              {
                // Continue sliced upload.
                bytesUploaded = uploadFile.ContinueUpload(uploadId, fileoffset, s);
                ctx.ExecuteQuery();
                // Update fileoffset for the next slice.
                fileoffset = bytesUploaded.Value;
              }
            }
          }
        } // while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
      }
    }
    finally
    {
      if (fs != null)
      {
        fs.Dispose();
      }
    }
  }

  return null;
}

【讨论】:

  • 我收到“rootweb”错误,我是否也需要导入一些东西?
  • 抱歉,这应该是当前上下文中对 Web 的引用。我已经更新了答案中的代码。
  • 成功了!谢谢你大王!
猜你喜欢
  • 2020-08-19
  • 2020-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2021-10-14
相关资源
最近更新 更多