public async Task getDownload2(String SelectedItem) { // Some of this code is based on question by Pavan Tiwari, 11/26/2012, and answer by Simon Mourier // https://stackoverflow.com/questions/13566302/download-large-file-in-small-chunks-in-c-sharp if (null == this.graphClient) { return; } long ChunkSize = DownloadDownloadChunkSize; long offset = 0; // cursor location for updating the Range header. byte[] bytesInStream; long Progress = 0; Label lb = (Label)System.Windows.Forms.Application.OpenForms["Form1"].Controls.Find("label4", false).FirstOrDefault(); // Get the collection of drive items. We'll only use one. IList <DriveItem> driveItems = await GetOnedriveFileList(); // get a list of items ogjects from onedrive from specific folder foreach (DriveItem item in driveItems) { if (item.Name.Equals(SelectedItem)) {// Item name to the selected item // Let's download the first file we get in the response. if (item.File != null) { Console.WriteLine(item.Name); // We'll use the file metadata to determine size and the name of the downloaded file // and to get the download URL. var driveItemInfo = await graphClient.Me.Drive.Items[item.Id].Request().GetAsync(); // Get the download URL. This URL is preauthenticated and has a short TTL. object downloadUrl; driveItemInfo.AdditionalData.TryGetValue("@microsoft.graph.downloadUrl", out downloadUrl); // Get the number of bytes to download. calculate the number of chunks and determine // the last chunk size. long size = (long)driveItemInfo.Size; int numberOfChunks = Convert.ToInt32(size / ChunkSize); // We are incrementing the offset cursor after writing the response stream to a file after each chunk. // Subtracting one since the size is 1 based, and the range is 0 base. There should be a better way to do // this but I haven't spent the time on that. int lastDownloadChunkSize = Convert.ToInt32(size % ChunkSize) - numberOfChunks - 1; if (lastDownloadChunkSize > 0) { numberOfChunks++; } Console.WriteLine("File Name = " + item.Name + "| Size = " + item.Size); var FileName = (string)Properties.Settings.Default["SaveDownloadFilesLocation"] + "\\" + driveItemInfo.Name; // Create a file stream to contain the downloaded file. using (FileStream fileStream = System.IO.File.Create((@FileName))) { for (int i = 0; i < numberOfChunks; i++) { // Setup the last chunk to request. This will be called at the end of this loop. if (i == numberOfChunks - 1) { ChunkSize = lastDownloadChunkSize; } // Create the request message with the download URL and Range header. HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, (string)downloadUrl); req.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(offset, ChunkSize + offset); // We can use the the client library to send this although it does add an authentication cost. // HttpResponseMessage response = await graphClient.HttpProvider.SendAsync(req); // Since the download URL is preauthenticated, and we aren't deserializing objects, // we'd be better to make the request with HttpClient. var client = new HttpClient(); HttpResponseMessage response = await client.SendAsync(req); using (Stream responseStream = await response.Content.ReadAsStreamAsync()) { //Console.WriteLine("bytesInStream : " + Progress); bytesInStream = new byte[ChunkSize]; int read; do { read = responseStream.Read(bytesInStream, 0, (int)bytesInStream.Length); if (read > 0) { fileStream.Write(bytesInStream, 0, read); } }while (read > 0); //Console.WriteLine(StaticHelpers.BytesToString(responseStream.Length)); Progress += responseStream.Length; //Console.WriteLine(StaticHelpers.BytesToString(Progress)); lb.Text = StaticHelpers.BytesToString(Progress) + " " + ($" from { StaticHelpers.BytesToString(size) }"); } offset += DownloadDownloadChunkSize + 1; // Move the offset cursor to the next chunk. } } return; } } } }
// Upload File to Onedrive public async Task <string> transferDataToOnedrive(String FilePath) { var fileName = Path.GetFileName(FilePath); if (null == this.graphClient) { return(""); } Label lb = (Label)System.Windows.Forms.Application.OpenForms["Form1"].Controls.Find("label4", false).FirstOrDefault(); using (var fileStream = System.IO.File.OpenRead(FilePath)) { // Use properties to specify the conflict behavior // in this case, replace var uploadProps = new DriveItemUploadableProperties { ODataType = null, 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 uploadSession = await graphClient.Me.Drive.Root .ItemWithPath("ClipboardShare/" + fileName) .CreateUploadSession(uploadProps) .Request() .PostAsync(); int maxSliceSize = UploadDownloadChunkSize; var fileUploadTask = new LargeFileUploadTask <DriveItem>(uploadSession, fileStream, maxSliceSize); // Create a callback that is invoked after each slice is uploaded IProgress <long> progress = new Progress <long>(progress => { Console.WriteLine($"Uploaded {progress} bytes of {fileStream.Length} bytes"); lb.Text = StaticHelpers.BytesToString(progress) + " " + ($" from { StaticHelpers.BytesToString(fileStream.Length) }"); }); try { // Upload the file var uploadResult = await fileUploadTask.UploadAsync(progress); if (uploadResult.UploadSucceeded) { // The ItemResponse object in the result represents the // created item. Console.WriteLine($"Upload complete, item ID: {uploadResult.ItemResponse.Id}"); } else { Console.WriteLine("Upload failed"); } } catch (ServiceException ex) { Console.WriteLine($"Error uploading: {ex.ToString()}"); } } lb.Text = ""; return(""); }