Compartilhar via


Exemplo de Suplemento do SharePoint de carregamento de arquivos grandes

O exemplo Core.LargeFileUpload mostra como usar um suplemento hospedado pelo provedor para carregar arquivos no SharePoint e como ignorar o limite de carregamento de arquivo de 2-MB.

Use esta solução para carregar arquivos maiores do que 2 MB no SharePoint.

Este exemplo é executado como um aplicativo de console que carrega arquivos em uma biblioteca de documentos usando um dos seguintes métodos:

A tabela a seguir lista os métodos de carregamento de arquivos que estão disponíveis e descrevem quando usar cada método.

Opções para carregar arquivos

Opção de carregamento de arquivo Considerações Quando você deve usar isso? Plataformas com suporte
Propriedade Conteúdo na classe FileCreationInformation. O tamanho máximo de arquivo que pode ser carregado é de 2 MB. O tempo limite ocorre após 30 minutos. Use somente para carregar arquivos com menos de 2 MB. SharePoint Server, SharePoint Online
SaveBinaryDirect método na classe arquivo. Não há limites de tamanho de arquivo. O tempo limite ocorre após 30 minutos. Apenas use este método se você estiver usando uma política de autenticação somente-usuário. Uma política de autenticação somente-usuário não está disponível em um suplemento do SharePoint, mas pode ser usada em suplementos nativos do dispositivo do Windows PowerShell e aplicativos de console do Windows. SharePoint Server, SharePoint Online
ContentStream propriedade na classe FileCreationInformation. Não há limites de tamanho de arquivo. O tempo limite ocorre após 30 minutos. Recomendado para:
- SharePoint Server
– SharePoint Online quando ele for menor do que 10 MB.
SharePoint Server, SharePoint Online
Carregue um único arquivo como um conjunto de fragmentos usando os métodos StartUpload, ContinueUploade FinishUpload na classe arquivo. Não há limites de tamanho de arquivo. O tempo limite ocorre após 30 minutos. Cada parte do arquivo deve carregar dentro de 30 minutos após a conclusão da parte anterior para evitar o tempo limite. Recomendado para o SharePoint Online quando o arquivo for maior do que 10 MB. SharePoint Online

Antes de começar

Para começar, faça o download do suplemento de exemplo Core.LargeFileUpload no projeto Padrões e práticas do Desenvolvedor do Office 365 no GitHub.

Observação

The code in this article is provided as-is, without warranty of any kind, either express or implied, including any implied warranties of fitness for a particular purpose, merchantability, or non-infringement.

Usando o suplemento de exemplo Core.LargeFileUpload

Quando você iniciar o código a seguir, um aplicativo do console aparecerá. Você deverá fornecer suas credenciais de logon e uma URL de conjunto de sites do SharePoint Online para Office 365.

Depois da autenticação, o aplicativo de console exibirá uma exceção. A exceção ocorre quando o método UploadDocumentContent no FileUploadService.cs tenta usar a propriedade FileCreationInformation.Content para carregar um arquivo maior que 2 MB. UploadDocumentContentUploadDocumentContent também cria uma biblioteca de documentos chamada Documentos caso ela ainda não exista. A biblioteca Documentosserá usada mais tarde no código a seguir.

public void UploadDocumentContent(ClientContext ctx, string libraryName, string filePath)
{
  Web web = ctx.Web;

  // Ensure that target library exists. Create if it is missing.
  if (!LibraryExists(ctx, web, libraryName))
  {
    CreateLibrary(ctx, web, libraryName);
  }

  FileCreationInformation newFile = new FileCreationInformation();

  // The next line of code causes an exception to be thrown for files larger than 2 MB.
  newFile.Content = System.IO.File.ReadAllBytes(filePath);
  newFile.Url = System.IO.Path.GetFileName(filePath);

  // Get instances to the given library.
  List docs = web.Lists.GetByTitle(libraryName);

  // Add file to the library.
  Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
  ctx.Load(uploadFile);
  ctx.ExecuteQuery();
}

Em FileUploadService.cs, esse exemplo de código fornece três opções que você pode usar para carregar arquivos grandes para uma biblioteca de documentos:

  • O métodoFile.SaveBinaryDirect.
  • A propriedadeFileCreationInformation.ContentStreamFileCreationInformation.ContentStream.
  • Os métodos StartUpload, ContinueUploade FinishUpload na classe arquivo.

Em FileUploadService.cs, SaveBinaryDirect usa o método Microsoft.SharePoint.Client.File.SaveBinaryDirect com um objeto FileStream para carregar arquivos em uma biblioteca de documentos.

public void SaveBinaryDirect(ClientContext ctx, string libraryName, string filePath)
{
  Web web = ctx.Web;
  // Ensure that the target library exists. Create it if it is missing.
  if (!LibraryExists(ctx, web, libraryName))
  {
    CreateLibrary(ctx, web, libraryName);
  }

  using (FileStream fs = new FileStream(filePath, FileMode.Open))
  {
    Microsoft.SharePoint.Client.File.SaveBinaryDirect(ctx, string.Format("/{0}/{1}", libraryName, System.IO.Path.GetFileName(filePath)), fs, true);
  }
}

Em FileUploadService.cs, UploadDocumentContentStream usa a propriedade FileCreationInformation.ContentStream com o objeto FileStream para carregar um arquivo em uma biblioteca de documentos.

public void UploadDocumentContentStream(ClientContext ctx, string libraryName, string filePath)
{
  Web web = ctx.Web;
  // Ensure that the target library exists. Create it if it is missing.
  if (!LibraryExists(ctx, web, libraryName))
  {
    CreateLibrary(ctx, web, libraryName);
  }

  using (FileStream fs = new FileStream(filePath, FileMode.Open))
  {
    FileCreationInformation flciNewFile = new FileCreationInformation();

    // This is the key difference for the first case - using ContentStream property
    flciNewFile.ContentStream = fs;
    flciNewFile.Url = System.IO.Path.GetFileName(filePath);
    flciNewFile.Overwrite = true;

    List docs = web.Lists.GetByTitle(libraryName);
    Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(flciNewFile);

    ctx.Load(uploadFile);
    ctx.ExecuteQuery();
  }
}

Em FileUploadService.cs, UploadFileSlicePerSlice carrega um arquivo grande em uma biblioteca de documentos como um conjunto de partes ou fragmentos. UploadFileSlicePerSlice executa as seguintes tarefas:

  1. Obtém um novo GUID. Para carregar um arquivo em partes, você deve usar um GUID exclusivo.
  2. Calcula o tamanho das partes em bytes. Para calcular o tamanho do bloco em bytes, UploadFileSlicePerSlice usa fileChunkSizeInMB, que especifica o tamanho dos blocos individuais em MB.
  3. Testa se o tamanho do arquivo a ser carregado (fileSize) é menor ou igual ao tamanho da parte (blockSize).
    • Se fileSize é menor ou igual ao tamanho da parte, a amostra garante que o arquivo ainda será carregado usando a propriedade FileCreationInformation.ContentStream. Lembre-se de que o tamanho recomendado da parte é de 10 MB ou mais.
    • Se fileSize for maior do que o tamanho da parte:
      • A parte do arquivo é lido em buffer
      • Se o tamanho da parte for igual ao tamanho do arquivo, o arquivo todo foi lido. O bloco é copiado para o lastBuffer. lastBuffer em seguida, o usa o File.FinishUpload para carregar o bloco.
    • Se o tamanho da parte não é igual ao tamanho do arquivo, há mais de uma parte para ler o arquivo. File.StartUpload o é chamado para carregar o primeiro bloco. fileoffset, que é usado como ponto de partida da próxima parte, é definido como a quantidade de bytes carregados da primeira parte. Quando a próxima parte é lida, se a última parte não tiver sido alcançada, File.ContinueUploadFile.ContinueUpload é chamado para carregar a próxima parte do arquivo. O processo se repete até que a última parte seja lida. Quando a última parte for lida File.FinishUpload carrega a última parte e compromete o arquivo. O conteúdo do arquivo será alterado em seguida, quando esse método estiver concluído.

Observação

Considere as seguintes práticas recomendadas:

  • Use um mecanismo de repetição caso o carregamento seja interrompido. Quando um arquivo carregado for interrompido, o arquivo será chamado de arquivo não concluído. Você pode reiniciar o carregamento de um arquivo inacabado logo após o carregamento ser interrompido. Arquivos não concluídos são removidos do servidor entre 6 e 24 horas após o arquivo não terminado ter sido interrompido. O período de remoção pode mudar sem aviso prévio.
  • Ao carregar um arquivo em partes para o SharePoint Online, um bloqueio é inserido no arquivo no SharePoint Online. Quando ocorrer uma interrupção, o arquivo permanecerá bloqueado para 15 minutos. Se a próxima parte do arquivo não for carregada no SharePoint Online dentro de 15 minutos, o bloqueio será removido. Após o bloqueio ser removido, você pode retomar o carregamento ou outro usuário pode começar a carregar o arquivo. Se outro usuário iniciar carregamento do arquivo, o arquivo não terminado será removido do SharePoint Online. O período de tempo que o bloqueio permanece em um arquivo depois do carregamento ser interrompido pode ser modificado sem aviso prévio.
  • Você pode alterar o tamanho da parte. É recomendável usar um tamanho de parte de 10 MB.
  • Retome uma parte interrompida ao controlar quais partes foram carregadas com êxito.

As partes devem ser carregadas em ordem sequencial. Você não pode carregar fatias ao mesmo tempo (por exemplo, usando uma abordagem multithread).

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;
}

Quando o código de exemplo for finalizado no seu site do Office 365, você pode ir para a biblioteca Documentos , escolhendo Documentos>Recentes. Verifique se a biblioteca Documentos contém três arquivos grandes.

Confira também