Reputation: 1773
I've been using the following method to upload images to Google Drive:
public string AddFile(string path, string contentType, string driveId)
{
FilesResource.CreateMediaUpload request;
using (FileStream stream = new FileStream(path,
FileMode.Open))
{
Google.Apis.Drive.v3.Data.File fileMetadata = new Google.Apis.Drive.v3.Data.File
{
Name = Path.GetFileName(path),
DriveId = driveId
};
request = _service.Files.Create(
fileMetadata, stream, contentType);
request.Fields = "id";
request.SupportsTeamDrives = true;
}
IUploadProgress requestResult = request.Upload();
if (requestResult.Exception != null) throw requestResult.Exception;
Google.Apis.Drive.v3.Data.File file = request.ResponseBody;
return file == null ? "" : file.Id;
}
It was working fine until today, using the API client library version 1.40.3.1694. Now I get this sort of error in requestResult.Exception:
System.FormatException: The format of value 'bytes 0--1/660915' is invalid.
The file I'm uploading is just a small GIF test file that gets deleted right away in this case.
Am I missing something obvious?
Upvotes: 3
Views: 383
Reputation: 1500385
I understand:
MemoryStream
fixes itI don't yet understand:
The problem is that you're opening a FileStream
, creating a request but not executing it, disposing of the FileStream
and then executing the request. In your MemoryStream
version, you don't dispose of the stream until the upload is complete.
Creating the initial request doesn't actually read the data from the stream - it just prepares things. You need to keep your stream open until Upload
has completed. So all you need to do is make the using
statement bigger:
public string AddFile(string path, string contentType, string driveId)
{
using (FileStream stream = new FileStream(path, FileMode.Open))
{
Google.Apis.Drive.v3.Data.File fileMetadata = new Google.Apis.Drive.v3.Data.File
{
Name = Path.GetFileName(path),
DriveId = driveId
};
var request = _service.Files.Create(fileMetadata, stream, contentType);
request.Fields = "id";
request.SupportsTeamDrives = true;
IUploadProgress requestResult = request.Upload();
if (requestResult.Exception != null) throw requestResult.Exception;
Google.Apis.Drive.v3.Data.File file = request.ResponseBody;
return file == null ? "" : file.Id;
}
}
Upvotes: 1
Reputation: 1773
Seems like the way to go about this correctly is to change the method to this:
public string AddFile(string path, string contentType, string driveId)
{
FilesResource.CreateMediaUpload request;
using (FileStream stream = new FileStream(path,
FileMode.Open))
{
using (MemoryStream memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
File fileMetadata = new Google.Apis.Drive.v3.Data.File
{
Name = Path.GetFileName(path),
DriveId = driveId
};
request = _service.Files.Create(
fileMetadata, memoryStream, contentType);
request.Fields = "id";
request.SupportsTeamDrives = true;
request.Upload();
}
}
File file = request.ResponseBody;
return file.Id;
}
You need to copy the file stream into a memory stream and upload from that instead. I'm still curious as to why that works, so if someone wants to get a checkmark, I would accept an answer that includes an explanation as to why this works but the one I put in my question doesn't.
Upvotes: 0