/// <summary> /// Reads this file content from the remote storage. /// </summary> /// <param name="offset">File content offset, in bytes, to start reading from.</param> /// <param name="length">Data length to read, in bytes.</param> /// <param name="fileSize">Total file size, in bytes.</param> /// <param name="resultContext"> /// You will use this parameter to return file content by /// calling <see cref="ITransferDataResultContext.ReturnData(byte[], long, long)"/> /// </param> public async Task ReadAsync(long offset, long length, long fileSize, ITransferDataResultContext resultContext) { // On Windows this method has a 60 sec timeout. // To process longer requests and reset the timout timer call the resultContext.ReportProgress() or resultContext.ReturnData() method. IFileAsync file = await Program.DavClient.OpenFileAsync(RemoteStorageUri); using (Stream stream = await file.GetReadStreamAsync(offset, fileSize)) { const long MAX_CHUNK_SIZE = 0x500000; //5Mb long chunkSize = Math.Min(MAX_CHUNK_SIZE, length); stream.Seek(offset, SeekOrigin.Begin); long total = offset + length; byte[] buffer = new byte[chunkSize]; long bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, (int)chunkSize)) > 0) { resultContext.ReturnData(buffer, offset, bytesRead); offset += bytesRead; length -= bytesRead; chunkSize = Math.Min(MAX_CHUNK_SIZE, length); if (offset >= total) { return; } } } }
/// <summary>Writes content on server.</summary> /// <param name="fileMetadata">The created file.</param> /// <param name="fileUrlPath">The file url path.</param> /// <returns>The <see cref="FileMetadata"/>.</returns> public FileMetadata WriteFileContentOnServer(FileMetadata fileMetadata, string fileUrlPath) { IFileAsync serverItem = fileMetadata.ServerFile; serverItem.TimeOut = 36000000; serverItem.UploadAsync(fileUrlPath).GetAwaiter().GetResult(); return(this.GetFileMetadata(fileMetadata.Identifier)); }
/// <summary>Get items from server and saves local.</summary> /// <param name="item">The item.</param> public void PullFromServer(FileMetadata item) { IFileAsync serverItem = item.ServerFile; item.ServerFile.TimeOut = 36000000; serverItem.DownloadAsync(item.LocalFile.Path).GetAwaiter().GetResult(); item.LocalFile.Etag = item.ServerFile.Etag; this.LocalStorage.UpdateFile(item.LocalFile); }
/// <summary>Creates file metadata.</summary> /// <param name="itemIdentifier">The item identifier.</param> /// <param name="localItem">The local item.</param> /// <param name="serverItem">The server item.</param> /// <returns>The <see cref="FileMetadata"/>.</returns> private FileMetadata CreateFileMetadata( string itemIdentifier, LocalFile localItem, IFileAsync serverItem = null) { string parentIdentifier = this.LocationMapper.GetParentIdentifier(itemIdentifier); string name = this.GetItemDisplayName(itemIdentifier, serverItem); return(new FileMetadata(itemIdentifier, parentIdentifier, name, localItem, serverItem)); }
/// <summary>Creates file on server.</summary> /// <param name="parentMetadata">The parent metadata.</param> /// <param name="fileName">The file name.</param> /// <returns>The <see cref="FileMetadata"/>.</returns> public FileMetadata CreateFileOnServer(FolderMetadata parentMetadata, string fileName) { IFileAsync newFile = parentMetadata.ServerFolder.CreateFileAsync(fileName, null).GetAwaiter().GetResult(); string identifier = this.LocationMapper.GetIdentifierFromServerUri(newFile.Href); string localPath = this.LocationMapper.GetLocalUrlFromIdentifier(identifier); LocalFile localItem = this.LocalStorage.GetFile(localPath); string name = this.GetItemDisplayName(identifier, newFile); return(new FileMetadata(identifier, parentMetadata.Identifier, name, localItem, newFile)); }
/// <summary>Initializes a new instance of the <see cref="FileMetadata"/> class.</summary> /// <param name="identifier">The identifier.</param> /// <param name="parentIdentifier">The parent identifier.</param> /// <param name="name">The name.</param> /// <param name="localItem">The local item.</param> /// <param name="serverItem">The server item.</param> public FileMetadata( string identifier, string parentIdentifier, string name, LocalFile localItem, IFileAsync serverItem = null) : base(identifier, parentIdentifier, name, localItem, serverItem) { this.LocalFile = localItem; this.ServerFile = serverItem; }
/// <inheritdoc/> public async Task ReadAsync(Stream output, long offset, long length, ITransferDataOperationContext operationContext, ITransferDataResultContext resultContext) { // On Windows this method has a 60 sec timeout. // To process longer requests and reset the timout timer call the resultContext.ReportProgress() or resultContext.ReturnData() method. Logger.LogMessage($"{nameof(IFile)}.{nameof(ReadAsync)}({offset}, {length})", UserFileSystemPath); SimulateNetworkDelay(length, resultContext); IFileAsync file = await Program.DavClient.OpenFileAsync(RemoteStoragePath); using (Stream stream = await file.GetReadStreamAsync(offset, length)) { const int bufferSize = 0x500000; // 5Mb. Buffer size must be multiple of 4096 bytes for optimal performance. await stream.CopyToAsync(output, bufferSize, length); } }
/// <summary>Gets file's local and remote state. </summary> /// <param name="itemIdentifier">The item identifier.</param> /// <returns>The <see cref="FileMetadata"/>.</returns> public FileMetadata GetFileMetadata(string itemIdentifier) { try { Uri serverUri = this.LocationMapper.GetServerUriFromIdentifier(itemIdentifier); IFileAsync serverItem = this.session.OpenFileAsync(serverUri).GetAwaiter().GetResult(); string localPath = this.LocationMapper.GetLocalUrlFromIdentifier(itemIdentifier); LocalFile localItem = this.LocalStorage.GetFile(localPath); return(this.CreateFileMetadata(itemIdentifier, localItem, serverItem)); } catch (NotFoundException) { string localPath = this.LocationMapper.GetLocalUrlFromIdentifier(itemIdentifier); LocalFile localItem = this.LocalStorage.GetFile(localPath); return(this.CreateFileMetadata(itemIdentifier, localItem)); } }
/// <summary> /// Reads file content from the remote storage. /// </summary> /// <param name="offset">Offset in bytes in file content to start reading from.</param> /// <param name="length">Lenth in bytes of the file content to read.</param> /// <returns>File content that corresponds to the provided offset and length.</returns> public async Task <byte[]> ReadAsync(long offset, long length) { // This method has a 60 sec timeout. // To process longer requests modify the IFolder.TransferDataAsync() implementation. IFileAsync file = await Program.DavClient.OpenFileAsync(RemoteStorageUri); using (Stream stream = await file.GetReadStreamAsync(offset, length)) { byte[] buffer = new byte[length]; int bufferPos = 0; int bytesRead = 0; while ((bytesRead = await stream.ReadAsync(buffer, bufferPos, (int)length)) > 0) { bufferPos += bytesRead; length -= bytesRead; } return(buffer); } }