Uploading
TTMSFNCCloudDropBox uploads a local file into a Dropbox folder, reporting
completion through an event. Dropbox accepts a file of up to 150 MB in a
single request; anything larger has to be sent in chunks through a
resumable upload session, which the component drives for you once you start
it. This chapter covers a normal upload, the resumable session for large
files, and how to choose between them.
Uploading a file
Upload sends a local file to a Dropbox folder. Use the folder-name overload
for a path, or the folder-item overload when you already hold the target
folder. OnUploadFile reports the created item. UploadMode controls the
conflict behavior when an item with the same name already exists at the
destination.
procedure TForm1.UploadReport;
begin
TMSFNCCloudDropBox1.OnUploadFile := DropBoxUploaded;
// Folder path; pass an empty string for the root.
TMSFNCCloudDropBox1.Upload('/Reports', 'C:\local\Q4.pdf');
end;
procedure TForm1.DropBoxUploaded(Sender: TObject; const AUploadItem: TTMSFNCCloudItem;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
if ARequestResult.Success then
ShowMessage('Uploaded as ' + AUploadItem.FileName)
else
ShowMessage('Upload failed: ' + ARequestResult.ResultString);
end;
Resumable uploads for large files
A file that will not fit in a single request goes through
UploadResumableFile instead. This is a separate call — Upload never
switches to a resumable session on its own. Describe the transfer with a
TTMSFNCCloudFile entry taken from the component's CloudFiles collection:
FilePath is the local file and DestinationPath is the Dropbox folder it is
written into (or pass the target folder item as the second argument to
UploadResumableFile). The first call sends the first chunk; each following
chunk is queued automatically from the previous one until the file is
complete.
OnUploadResumableFile reports each chunk as it completes and is where you
drive a progress bar — TTMSFNCCloudFile.Position holds the confirmed offset
and GetFileSize the total. OnUploadResumableFileFinished fires once the
last chunk lands, and OnUploadResumableFileFailed reports a failed chunk.
Because Position and SessionID survive a failure, handing the same
TTMSFNCCloudFile back to UploadResumableFile resumes the transfer where it
stopped instead of restarting it.
procedure TForm1.UploadLargeFile;
var
CloudFile: TTMSFNCCloudFile;
begin
TMSFNCCloudDropBox1.OnUploadResumableFile := DropBoxChunkUploaded;
TMSFNCCloudDropBox1.OnUploadResumableFileFinished := DropBoxUploadFinished;
TMSFNCCloudDropBox1.OnUploadResumableFileFailed := DropBoxUploadFailed;
// The resumable session is driven from a TTMSFNCCloudFile entry: FilePath is
// the local file, DestinationPath the Dropbox folder it is written into.
CloudFile := TMSFNCCloudDropBox1.CloudFiles.Add;
CloudFile.FilePath := 'C:\local\database-backup.bak';
CloudFile.DestinationPath := '/Backups';
// Sends the first chunk; every following chunk is queued automatically from
// the completion of the previous one until the file is fully uploaded.
TMSFNCCloudDropBox1.UploadResumableFile(CloudFile);
end;
procedure TForm1.DropBoxChunkUploaded(Sender: TObject; const ACloudFile: TTMSFNCCloudFile;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
if ARequestResult.Success and (ACloudFile.GetFileSize > 0) then
ProgressBar1.Value := ACloudFile.Position / ACloudFile.GetFileSize * 100;
end;
procedure TForm1.DropBoxUploadFinished(Sender: TObject; const ACloudFile: TTMSFNCCloudFile;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
if ARequestResult.Success then
ShowMessage('Upload complete: ' + ACloudFile.FilePath);
end;
procedure TForm1.DropBoxUploadFailed(Sender: TObject; const ACloudFile: TTMSFNCCloudFile;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
// Position still holds the last confirmed offset, so the same CloudFile can
// be handed to UploadResumableFile again to resume where it stopped.
ShowMessage('Upload failed: ' + ARequestResult.ResultString);
end;
Choosing between a single and a resumable upload
Code that handles files of unpredictable size has to pick the path itself.
Check the size first and route small files through Upload and large ones
through UploadResumableFile, wiring both completion events so either outcome
is reported:
procedure TForm1.UploadFileOfAnySize(const ALocalFile: string);
const
ResumableThreshold = 100 * 1024 * 1024; // Dropbox caps a single upload at 150 MB.
var
CloudFile: TTMSFNCCloudFile;
begin
TMSFNCCloudDropBox1.OnUploadFile := DropBoxUploadFileDone;
TMSFNCCloudDropBox1.OnUploadResumableFileFinished := DropBoxUploadResumableDone;
TMSFNCCloudDropBox1.OnUploadResumableFileFailed := DropBoxUploadResumableFailed;
CloudFile := TMSFNCCloudDropBox1.CloudFiles.Add;
CloudFile.FilePath := ALocalFile;
CloudFile.DestinationPath := '/Backups';
if CloudFile.GetFileSize < ResumableThreshold then
// Small enough for a single request; completes in OnUploadFile.
TMSFNCCloudDropBox1.Upload(CloudFile.DestinationPath, CloudFile.FilePath)
else
// Too large for one request; completes in OnUploadResumableFileFinished.
TMSFNCCloudDropBox1.UploadResumableFile(CloudFile);
end;
procedure TForm1.DropBoxUploadFileDone(Sender: TObject; const AUploadItem: TTMSFNCCloudItem;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
if ARequestResult.Success then
ShowMessage('Uploaded as ' + AUploadItem.FileName);
end;
procedure TForm1.DropBoxUploadResumableDone(Sender: TObject; const ACloudFile: TTMSFNCCloudFile;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
if ARequestResult.Success then
ShowMessage('Uploaded (resumable): ' + ACloudFile.FilePath);
end;
procedure TForm1.DropBoxUploadResumableFailed(Sender: TObject; const ACloudFile: TTMSFNCCloudFile;
const ARequestResult: TTMSFNCCloudBaseRequestResult);
begin
ShowMessage('Resumable upload failed: ' + ARequestResult.ResultString);
end;
Common mistakes
- Assuming
Uploadis synchronous.Uploadreturns before the transfer finishes; act on the result inOnUploadFile(or, in synchronous mode, on the return value — see Folder and file operations). - Expecting
Uploadto chunk a large file. It does not. A file over the provider's single-request limit must go throughUploadResumableFile, and it completes throughOnUploadResumableFileFinished, neverOnUploadFile. - Creating the
TTMSFNCCloudFileyourself. Take it fromCloudFiles.Addso the component owns it for the lifetime of the session; a resumable upload reads and updatesPosition,SessionIDandUploadedon that entry across several requests.
Related API
TTMSFNCCloudDropBox—Upload,UploadResumableFile,UploadMode,CloudFiles,OnUploadFile,OnUploadResumableFile,OnUploadResumableFileFinished,OnUploadResumableFileFailed