Hochladen großer Dateien – SharePoint-Beispiel-Add-In
In dem Core.LargeFileUpload-Beispiel wird gezeigt, wie Sie mit einem vom Anbieter gehosteten Add-In große Dateien in SharePoint hochladen und die maximale Dateigröße von 2 MB beim Hochladen umgehen können.
Verwenden Sie diese Lösung, wenn Sie Dateien, die größer als 2 MB sind, in SharePoint hochladen möchten.
In diesem Beispiel wird eine Konsolenanwendung ausgeführt, mit der große Dateien mithilfe einer der folgenden Methoden in einer Dokumentbibliothek hochgeladen werden:
- Die SaveBinaryDirect-Methode der Microsoft.SharePoint.Client.File -Klasse.
- Die ContentStream-Eigenschaft der FileCreationInformation-Klasse.
- Die StartUpload-, ContinueUpload- und FinishUpload-Methoden der File-Klasse.
In der folgenden Tabelle werden die Methoden zum Hochladen von Dateien und deren Verwendung erläutert.
Optionen für das Hochladen von Dateien
Option für das Hochladen der Datei | Überlegungen | Wann sollte sie verwendet werden | Unterstützte Plattformen |
---|---|---|---|
Die Content-Eigenschaft der FileCreationInformation-Klasse. | Maximale Dateigröße, die hochgeladen werden kann, beträgt 2 MB. Zeitüberschreitung nach 30 Minuten. | Verwenden Sie diese Methode, wenn Sie Dateien hochladen, die kleiner als 2 MB sind. | SharePoint Server, SharePoint Online |
SaveBinaryDirect -Methode für die File-Klasse. |
Keine Dateigrößenbeschränkungen. Zeitüberschreitung nach 30 Minuten. | Verwenden Sie diese Methode nur, wenn Sie eine Richtlinie zu Benutzerauthentifzierungen verwenden. Eine Nur-Benutzer-Authentifizierungsrichtlinie ist in einem SharePoint-Add-In nicht verfügbar, kann aber in systemeigenen Geräte-Add-Ins, Windows PowerShell- und Windows-Konsolenanwendungen verwendet werden. | SharePoint Server, SharePoint Online |
ContentStream -Eigenschaft für die FileCreationInformation-Klasse. |
Keine Dateigrößenbeschränkungen. Zeitüberschreitung nach 30 Minuten. | Empfohlen für: - SharePoint Server - SharePoint Online, wenn die Datei kleiner als 10 MB ist. |
SharePoint Server, SharePoint Online |
Laden Sie eine einzelne Datei mit den Methoden StartUpload , ContinueUpload und FinishUpload in der File-Klasse als Gruppe von Chunks hoch. |
Keine Dateigrößenbeschränkungen. Zeitüberschreitung nach 30 Minuten. Jeder Datenblock muss innerhalb von 30 Minuten nach Fertigstellung des vorherigen Blocks hochgeladen werden, um eine Zeitüberschreitung zu vermeiden. | Empfohlen für SharePoint Online, wenn die Datei größer als 10 MB ist. | SharePoint Online |
Bevor Sie beginnen:
Laden Sie zunächst das Core.LargeFileUpload-Beispiel-Add-In aus dem Projekt „Office 365-Entwicklermuster und -vorgehensweisen“ auf GitHub herunter.
Hinweis
Der Code in diesem Artikel wird wie besehen und ohne jegliche Garantie zur Verfügung gestellt, gleich ob ausdrücklich oder konkludent, einschließlich jedweder stillschweigenden Gewährleistung der Eignung für einen bestimmten Zweck, Marktgängigkeit oder Nichtverletzung von Rechten.
Verwenden des Core.LargeFileUpload Beispiel-Add-Ins
Beim Starten dieses Codebeispiels wird eine Konsolenanwendung geöffnet. Sie müssen eine SharePoint Online-Websitesammlungs-URL und Ihre Anmeldeinformationen für Office 365 angeben.
Nach der Authentifizierung zeigt die Konsolenanwendung eine Ausnahme an. Die Ausnahme tritt auf, wenn die UploadDocumentContent
-Methode in FileUploadService.cs versucht, die FileCreationInformation.Content
-Eigenschaft zum Hochladen einer Datei zu verwenden, die größer als 2 MB ist. UploadDocumentContent
erstellt auch eine Dokumentbibliothek namens Docs, wenn diese noch nicht vorhanden ist. Die Dokumentbibliothek Dokumente wird weiter unten in diesem Codebeispiel verwendet.
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();
}
In FileUploadService.cs bietet dieses Codebeispiel drei Optionen, die Sie zum Hochladen großer Dateien in eine Dokumentbibliothek verwenden können:
- Die
File.SaveBinaryDirect
-Methode. - Die
FileCreationInformation.ContentStream
-Eigenschaft. - Die Methoden
StartUpload
,ContinueUpload
undFinishUpload
für die File-Klasse.
In FileUploadService.cs verwendet SaveBinaryDirect
die Microsoft.SharePoint.Client.File.SaveBinaryDirect
-Methode mit einem FileStream
-Objekt, um Dateien in eine Dokumentbibliothek hochzuladen.
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);
}
}
In FileUploadService.csUploadDocumentContentStream
verwendet die FileCreationInformation.ContentStream
-Eigenschaft mit dem FileStream
-Objekt, um eine Datei in eine Dokumentbibliothek hochzuladen.
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();
}
}
In FileUploadService.csUploadFileSlicePerSlice
lädt eine große Datei als Gruppe von Blöcken oder Fragmenten in eine Dokumentbibliothek hoch. UploadFileSlicePerSlice
führt die folgenden Aufgaben aus:
- Ruft eine neue GUID ab. Um eine Datei in Datenblöcken hochzuladen, müssen Sie eine eindeutige GUID verwenden.
- Berechnet die Blockgröße eines Abschnitts in Byte. Zum Berechnen der Blockgröße in Bytes wird verwendet
fileChunkSizeInMB
,UploadFileSlicePerSlice
um die Größe der einzelnen Blöcke in MB angibt. - Testet, ob die Größe der hochzuladenden Datei (
fileSize
) kleiner oder gleich der Bockgröße (blockSize
) ist.- Wenn
fileSize
kleiner als oder gleich der Blockgröße ist, wird in dem Beispiel sichergestellt, dass die Datei mithilfe derFileCreationInformation.ContentStream
-Eigenschaft dennoch hochgeladen wird. Denken Sie daran, dass die empfohlene Blockgröße bei 10 MB und größer liegt. - Wenn
fileSize
größer als die Blockgröße ist:- Ein Block der Datei wird in
buffer
gelesen. - Wenn die Blockgröße gleich der Dateigröße ist, wird die gesamte Datei gelesen. Der Block wird in
lastBuffer
kopiert.lastBuffer
verwendetFile.FinishUpload
dann , um den Block hochzuladen.
- Ein Block der Datei wird in
- Ist die Blockgröße nicht gleich der Dateigröße, gibt es mehr als einen Datenblock, der aus der Datei zu lesen ist.
File.StartUpload
wird aufgerufen, um den ersten Block hochzuladen.fileoffset
, das als Anfang des nächsten Datenblocks verwendet wird, wird dann auf die Anzahl der aus dem ersten Datenblock hochgeladenen Bytes festgelegt. Beim Lesen des nächsten Datenblocks wird, falls der letzte Block noch nicht erreicht wurde,File.ContinueUpload
aufgerufen, um den nächsten Datenblock der Datei hochzuladen. Der Vorgang wird wiederholt, bis der letzte Block gelesen wurde. Beim Lesen des letzten Datenblocks lädtFile.FinishUpload
den letzten Block hoch und übergibt die Datei. Der Dateiinhalt wird dann geändert, wenn diese Methode ausgeführt wurde.
- Wenn
Hinweis
Berücksichtigen die folgenden bewährten Methoden:
- Verwenden Sie einen Wiederholungsmechanismus für den Fall, dass der Upload unterbrochen wird. Wenn das Hochladen einer Datei unterbrochen wird, wird die Datei „nicht fertig gestellte Datei“ genannt. Möglicherweise möchten Sie mit dem Hochladen einer nicht fertig gestellten Datei unmittelbar nach der Unterbrechung des Uploads erneut beginnen. Nicht fertig gestellte Dateien werden in dem Zeitraum zwischen 6 Stunden und 24 Stunden, nachdem das Hochladen der Datei unterbrochen wurde, auf dem Server entfernt. Dieser Zeitraum kann sich ohne vorherige Ankündigung ändern.
- Beim Hochladen einer Datei in Datenblöcken in SharePoint Online, wird die Datei in SharePoint Online gesperrt. Wenn eine Unterbrechung auftritt, bleibt die Datei 15 Minuten gesperrt. Wird der nächste Datenblock der Datei nicht innerhalb von 15 Minuten in SharePoint Online hochgeladen, wird die Datei freigegeben. Nach der Freigabe können Sie mit dem Hochladen der Datei fortfahren, oder ein anderer Benutzer kann mit dem Hochladen der Datei beginnen. Beginnt ein anderer Benutzer mit dem Hochladen der Datei, wird die noch nicht fertig gestellte Datei aus SharePoint Online entfernt. Die Dauer, für die eine Datei gesperrt ist, nachdem das Hochladen unterbrochen wurde, kann sich ohne vorherige Ankündigung ändern.
- Sie möchten die Blockgröße ggf. ändern. Es wird empfohlen, eine Blockgröße von 10 MB zu verwenden.
- Verfolgen Sie beim Fortsetzen des Hochladens eines unterbrochenen Datenblocks nach, welche Datenblöcke bereits erfolgreich hochgeladen wurden.
Datenblöcke müssen in einer sequenziellen Reihenfolge hochgeladen werden. Sie können Slices nicht gleichzeitig hochladen (z. B. mithilfe eines Multithread-Ansatzes).
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;
}
Navigieren Sie nach Abschluss des Codebeispiels auf Ihrer Office 365-Website zur Dokumentbibliothek Dokumente, indem Sie Zuletzt verwendet>Dokumente auswählen. Überprüfen Sie, ob die Dokumentbibliothek Dokumente drei große Dateien enthält.