public void WriteRootFolders() { VirtualFolder root = VirtualFolder.CreateRootFolder(Facade); foreach (var fileInfo in root.GetFiles("*.txt")) { var token = Facade.DownloadTransfers.RequestDownloadToken(fileInfo.MetaData.FullName, false); Func<long, StreamedDataBlock> func = n => { var db = Facade.DownloadTransfers.ReadBlockStreamed(token.TransferId, n); return db; }; using(var s = new StreamedBlockInputStream(func, token.ResourceLength)) { StreamReader reader = new StreamReader(s); var text = reader.ReadToEnd(); Console.Out.WriteLine("Read text:\n" + text); Console.Out.WriteLine(""); } // using(var stream = Facade.DownloadTransfers.ReadFile(fileInfo.MetaData.FullName)) // { // StreamReader reader = new StreamReader(stream); // var text = reader.ReadToEnd(); // // } } }
/// <summary> /// Gets one stream that allows reading the whole resource. /// </summary> /// <param name="transferId">Identifies the transfer and resource.</param> /// <returns>A stream that provides read access to the requested resource's data.</returns> /// <remarks>This implementation piggy-backs on the capabilities to read file in blocks. /// This causes overhead (we could just return the stream), but has the advantage that /// if the transfer is aborted (e.g. because a file lock expires), the underlying resource /// is immediately unlocked, because the returned stream does not directly access the /// resource data, but merely reads block after block via <see cref="ReadBlock"/>.</remarks> public Stream ReadResourceStreamed(string transferId) { // //TODO in providers stream getting method - just forward here // IDownloadTransferService srv = this...; // var token = srv.RequestDownloadToken(resourceId, false); // return srv.ReadResourceStreamed(token.TransferId); DownloadTransfer transfer = GetCachedTransfer(transferId, true); var stream = new StreamedBlockInputStream(blockNumber => ReadBlockStreamed(transferId, blockNumber), transfer.File.Length); return(stream); }
private Stream DownloadFileImpl(string transferId) { const FileSystemTask context = FileSystemTask.StreamedFileDownloadRequest; //get the cached transfer TTransfer transfer = GetCachedTransfer(transferId, true, context); if (transfer.Token.TotalBlockCount == 0) { //if we don't have any blocks, return a null stream Auditor.AuditTransferOperation(context, AuditEvent.FileDataDownloaded, transfer.TransferId, transfer.FileItem); return(Stream.Null); } //we don't expose the underlying stream directly, but rather use blocks again, //which disconnects the exposed stream from the underlying resource and allows for simple //aborting long resourceLength = transfer.FileItem.ResourceInfo.Length; // ReSharper disable UseObjectOrCollectionInitializer var stream = new StreamedBlockInputStream(blockNumber => ReadBlockStreamed(transferId, blockNumber), resourceLength); // ReSharper restore UseObjectOrCollectionInitializer //assign the stream the transfer object in order so it can query the status during reading stream.Transfer = transfer; //reading the last block closes the transfer automatically.. transfer.AutoCloseAfterLastBlockDelivery = true; //...and so does disposing the stream at any time var closingStream = new ClosingActionStream(stream, () => CompleteTransfer(transferId)); Auditor.AuditTransferOperation(context, AuditEvent.FileDataDownloaded, transfer.TransferId, transfer.FileItem); return(closingStream); }