Hochladen großer Dateien mithilfe der Microsoft Graph SDKs
Artikel
Viele Entitäten in Microsoft Graph unterstützen fortsetzbare Dateiuploads , um das Hochladen großer Dateien zu vereinfachen. Anstatt zu versuchen, die gesamte Datei in einer einzelnen Anforderung hochzuladen, wird die Datei in kleinere Teile aufgeteilt, und eine Anforderung wird verwendet, um einen einzelnen Slice hochzuladen. Um diesen Prozess zu vereinfachen, implementieren die Microsoft Graph SDKs eine Aufgabe zum Hochladen großer Dateien, die das Hochladen der Slices verwaltet.
using var fileStream = File.OpenRead(filePath);
// Use properties to specify the conflict behavior
// using DriveUpload = Microsoft.Graph.Drives.Item.Items.Item.CreateUploadSession;
var uploadSessionRequestBody = new DriveUpload.CreateUploadSessionPostRequestBody
{
Item = new DriveItemUploadableProperties
{
AdditionalData = new Dictionary<string, object>
{
{ "@microsoft.graph.conflictBehavior", "replace" },
},
},
};
// Create the upload session
// itemPath does not need to be a path to an existing item
var myDrive = await graphClient.Me.Drive.GetAsync();
var uploadSession = await graphClient.Drives[myDrive?.Id]
.Items["root"]
.ItemWithPath(itemPath)
.CreateUploadSession
.PostAsync(uploadSessionRequestBody);
// Max slice size must be a multiple of 320 KiB
int maxSliceSize = 320 * 1024;
var fileUploadTask = new LargeFileUploadTask<DriveItem>(
uploadSession, fileStream, maxSliceSize, graphClient.RequestAdapter);
var totalLength = fileStream.Length;
// Create a callback that is invoked after each slice is uploaded
IProgress<long> progress = new Progress<long>(prog =>
{
Console.WriteLine($"Uploaded {prog} bytes of {totalLength} bytes");
});
try
{
// Upload the file
var uploadResult = await fileUploadTask.UploadAsync(progress);
Console.WriteLine(uploadResult.UploadSucceeded ?
$"Upload complete, item ID: {uploadResult.ItemResponse.Id}" :
"Upload failed");
}
catch (ODataError ex)
{
Console.WriteLine($"Error uploading: {ex.Error?.Message}");
}
byteStream, _ := os.Open(largeFile)
// Use properties to specify the conflict behavior
itemUploadProperties := models.NewDriveItemUploadableProperties()
itemUploadProperties.SetAdditionalData(map[string]any{"@microsoft.graph.conflictBehavior": "replace"})
uploadSessionRequestBody := drives.NewItemItemsItemCreateUploadSessionPostRequestBody()
uploadSessionRequestBody.SetItem(itemUploadProperties)
// Create the upload session
// itemPath does not need to be a path to an existing item
myDrive, _ := graphClient.Me().Drive().Get(context.Background(), nil)
uploadSession, _ := graphClient.Drives().
ByDriveId(*myDrive.GetId()).
Items().
ByDriveItemId("root:/"+itemPath+":").
CreateUploadSession().
Post(context.Background(), uploadSessionRequestBody, nil)
// Max slice size must be a multiple of 320 KiB
maxSliceSize := int64(320 * 1024)
fileUploadTask := fileuploader.NewLargeFileUploadTask[models.DriveItemable](
graphClient.RequestAdapter,
uploadSession,
byteStream,
maxSliceSize,
models.CreateDriveItemFromDiscriminatorValue,
nil)
// Create a callback that is invoked after each slice is uploaded
progress := func(progress int64, total int64) {
fmt.Printf("Uploaded %d of %d bytes\n", progress, total)
}
// Upload the file
uploadResult := fileUploadTask.Upload(progress)
if uploadResult.GetUploadSucceeded() {
fmt.Printf("Upload complete, item ID: %s\n", *uploadResult.GetItemResponse().GetId())
} else {
fmt.Print("Upload failed.\n")
}
// Get an input stream for the file
File file = new File(filePath);
InputStream fileStream = new FileInputStream(file);
long streamSize = file.length();
// Set body of the upload session request
CreateUploadSessionPostRequestBody uploadSessionRequest = new CreateUploadSessionPostRequestBody();
DriveItemUploadableProperties properties = new DriveItemUploadableProperties();
properties.getAdditionalData().put("@microsoft.graph.conflictBehavior", "replace");
uploadSessionRequest.setItem(properties);
// Create an upload session
// ItemPath does not need to be a path to an existing item
String myDriveId = graphClient.me().drive().get().getId();
UploadSession uploadSession = graphClient.drives()
.byDriveId(myDriveId)
.items()
.byDriveItemId("root:/"+itemPath+":")
.createUploadSession()
.post(uploadSessionRequest);
// Create the upload task
int maxSliceSize = 320 * 10;
LargeFileUploadTask<DriveItem> largeFileUploadTask = new LargeFileUploadTask<>(
graphClient.getRequestAdapter(),
uploadSession,
fileStream,
streamSize,
maxSliceSize,
DriveItem::createFromDiscriminatorValue);
int maxAttempts = 5;
// Create a callback used by the upload provider
IProgressCallback callback = (current, max) -> System.out.println(
String.format("Uploaded %d bytes of %d total bytes", current, max));
// Do the upload
try {
UploadResult<DriveItem> uploadResult = largeFileUploadTask.upload(maxAttempts, callback);
if (uploadResult.isUploadSuccessful()) {
System.out.println("Upload complete");
System.out.println("Item ID: " + uploadResult.itemResponse.getId());
} else {
System.out.println("Upload failed");
}
} catch (CancellationException ex) {
System.out.println("Error uploading: " + ex.getMessage());
}
// Create a file stream
$file = GuzzleHttp\Psr7\Utils::streamFor(fopen($filePath, 'r'));
// Create the upload session request
$uploadProperties = new Models\DriveItemUploadableProperties();
$uploadProperties->setAdditionalData([
'@microsoft.graph.conflictBehavior' => 'replace'
]);
// use Microsoft\Graph\Generated\Drives\Item\Items\Item\CreateUploadSession\CreateUploadSessionPostRequestBody
// as DriveItemCreateUploadSessionPostRequestBody;
$uploadSessionRequest = new DriveItemCreateUploadSessionPostRequestBody();
$uploadSessionRequest->setItem($uploadProperties);
// Create the upload session
/** @var Models\Drive $drive */
$drive = $graphClient->me()->drive()->get()->wait();
$uploadSession = $graphClient->drives()
->byDriveId($drive->getId())
->items()
->byDriveItemId('root:/'.$itemPath.':')
->createUploadSession()
->post($uploadSessionRequest)
->wait();
$largeFileUpload = new LargeFileUploadTask($uploadSession, $graphClient->getRequestAdapter(), $file);
$totalSize = $file->getSize();
$progress = fn($prog) => print('Uploaded '.$prog[1].' of '.$totalSize.' bytes'.PHP_EOL);
try {
$largeFileUpload->upload($progress)->wait();
} catch (\Psr\Http\Client\NetworkExceptionInterface $ex) {
$largeFileUpload->resume()->wait();
}
// readFile from fs/promises
const file = await readFile(filePath);
// basename from path
const fileName = basename(filePath);
const options: OneDriveLargeFileUploadOptions = {
// Relative path from root folder
path: targetFolderPath,
fileName: fileName,
rangeSize: 1024 * 1024,
uploadEventHandlers: {
// Called as each "slice" of the file is uploaded
progress: (range, _) => {
console.log(`Uploaded bytes ${range?.minValue} to ${range?.maxValue}`);
},
},
};
// Create FileUpload object
const fileUpload = new FileUpload(file, fileName, file.byteLength);
// Create a OneDrive upload task
const uploadTask = await OneDriveLargeFileUploadTask.createTaskWithFileObject(
graphClient,
fileUpload,
options,
);
// Do the upload
const uploadResult: UploadResult = await uploadTask.upload();
// The response body will be of the corresponding type of the
// item being uploaded. For OneDrive, this is a DriveItem
const driveItem = uploadResult.responseBody as DriveItem;
console.log(`Uploaded file with ID: ${driveItem.id}`);
Fortsetzen eines Dateiuploads
Die Microsoft Graph SDKs unterstützen das Fortsetzen laufender Uploads. Wenn bei Ihrer Anwendung während des Uploads eine Verbindungsunterbrechung oder ein HTTP-Status 5.x.x auftritt, können Sie den Upload fortsetzen.
// Create message
var draftMessage = new Message
{
Subject = "Large attachment",
};
var savedDraft = await graphClient.Me
.Messages
.PostAsync(draftMessage);
using var fileStream = File.OpenRead(filePath);
var largeAttachment = new AttachmentItem
{
AttachmentType = AttachmentType.File,
Name = Path.GetFileName(filePath),
Size = fileStream.Length,
};
// using AttachmentUpload = Microsoft.Graph.Me.Messages.Item.Attachments.CreateUploadSession;
var uploadSessionRequestBody = new AttachmentUpload.CreateUploadSessionPostRequestBody
{
AttachmentItem = largeAttachment,
};
var uploadSession = await graphClient.Me
.Messages[savedDraft?.Id]
.Attachments
.CreateUploadSession
.PostAsync(uploadSessionRequestBody);
// Max slice size must be a multiple of 320 KiB
int maxSliceSize = 320 * 1024;
var fileUploadTask =
new LargeFileUploadTask<FileAttachment>(uploadSession, fileStream, maxSliceSize, graphClient.RequestAdapter);
var totalLength = fileStream.Length;
// Create a callback that is invoked after each slice is uploaded
IProgress<long> progress = new Progress<long>(prog =>
{
Console.WriteLine($"Uploaded {prog} bytes of {totalLength} bytes");
});
try
{
// Upload the file
var uploadResult = await fileUploadTask.UploadAsync(progress);
Console.WriteLine(uploadResult.UploadSucceeded ? "Upload complete" : "Upload failed");
}
catch (ODataError ex)
{
Console.WriteLine($"Error uploading: {ex.Error?.Message}");
}