File upload/download API
API operations often involve the transfer of large files (translation documents and bilinguals). Therefore, a unified and reliable transfer method has been introduced, that can be used throughout the API, involving chunked transfer and an option to handle compressed data. The file transfer API provides the following functionality:
- Chunked file upload, optionally zipped. For example, if a translation document is to be imported to a server project, then it has to be uploaded first by using file transfer upload operations.
- Chunked file download, optionally zipped. For example, if a translation document is exported, then the resulting file is created and temporarily stored on the server. Then the file can be downloaded by using file transfer download operations.
Demo code in C# for using the file manager service:
class FileManager
{
/// <summary>
/// Uploads a file given by its path.
/// </summary>
/// <param name="fmService">The IFileManagerService service proxy.</param>
/// <param name="filePath">The file path.</param>
/// <returns>The Guid of the uploaded file.</returns>
public static Guid UploadFile(IFileManagerService fmService, string filePath)
{
FileStream fileStream = null;
Guid fileGuid = Guid.Empty;
const int chunkSize = 500000;
byte[] chunkBytes = new byte[chunkSize];
byte[] dataToUpload;
int bytesRead;
try
{
// Open souce file stream
fileStream = File.OpenRead(filePath);
// Begin chunked upload
fileGuid = fmService.BeginChunkedFileUpload(filePath, false);
// Upload chunks
while ((bytesRead = fileStream.Read(chunkBytes, 0, chunkSize)) != 0)
{
if (bytesRead == chunkSize)
dataToUpload = chunkBytes;
else
{
// If we are at the end, we want to upload only
// the bytes read from the stream.
dataToUpload = new byte[bytesRead];
Array.Copy(chunkBytes, dataToUpload, bytesRead);
}
fmService.AddNextFileChunk(fileGuid, dataToUpload);
}
return fileGuid;
}
finally
{
if (fileStream != null)
fileStream.Close();
// End chunked upload
if (fileGuid != Guid.Empty)
fmService.EndChunkedFileUpload(fileGuid);
}
}
/// <summary>
/// Downloads a file given by its Guid.
/// </summary>
/// <param name="fmService">The IFileManagerService service proxy.</param>
/// <param name="fileGuid">The file GUID.</param>
/// <param name="fileName">Name of the file.</param>
/// <param name="targetdir">The target directory.</param>
public static void DownloadFile(IFileManagerService fmService, Guid fileGuid,
out string fileName, string targetdir)
{
FileStream fileStream = null;
Guid sessionGuid = Guid.Empty;
const int chunkSize = 500000;
byte[] chunkBytes;
int fileSize;
int fileBytesLeft;
try
{
sessionGuid = fmService.BeginChunkedFileDownload(
fileGuid,
false,
out fileName,
out fileSize);
fileStream = new FileStream(Path.Combine(targetdir, fileName),
FileMode.Create);
fileBytesLeft = fileSize;
while (fileBytesLeft > 0)
{
chunkBytes = fmService.GetNextFileChunk(sessionGuid, chunkSize);
fileStream.Write(chunkBytes, 0, chunkBytes.Length);
fileBytesLeft -= chunkBytes.Length;
}
}
finally
{
if (fileStream != null)
fileStream.Close();
try
{
if (sessionGuid != Guid.Empty)
fmService.EndChunkedFileDownload(sessionGuid);
// We no longer need the file, delete it on the server.
fmService.DeleteFile(fileGuid);
}
catch (Exception e)
{
Log.WriteVerbose(e.ToString());
// We are not interested in these errors. And don't want the
// original error to be hidden by these exceptions.
}
}
}
}