[英]How to save data from stream to file in WinRT?
我想有一個方法,將System.IO.Stream作為輸入並將其從其中寫入數據到文件中。 到目前為止,我有以下內容:
public async Task SaveStreamToFileX(Stream stream, string filePath, IProgress<long> progress)
{
var folder = await StorageFolder.GetFolderFromPathAsync(Path.GetDirectoryName(filePath));
var fileName = Path.GetFileName(filePath);
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
var istream = stream.AsInputStream();
var canRead = stream.CanRead; //this returns true
using (var reader = new DataReader(istream))
{
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter writer = new DataWriter(outputStream))
{
IBuffer buffer;
long readBytes = 0;
const int bufferSize = 8192;
while ((buffer = reader.ReadBuffer(bufferSize)).Length > 0) //exception System.Exception with message: Out of range ...
{
writer.WriteBuffer(buffer);
readBytes += bufferSize;
progress.Report(readBytes);
}
}
}
}
}
}
問題是,當我嘗試在while周期(首次讀取)中讀取數據時,引發了異常(超出范圍)。 流應該有數據。 我不確定是否需要這么長時間的代碼,如果有人有更好的解決方案,那會很棒。 旁注:如果我嘗試await reader.LoadAsync(50)
它將返回50。我不確定LoadAsync應該做什么。 也許我必須在讀取之前調用它以准備讀取的數據? 我將對此進行進一步調查。此外,Stream.CanRead返回true。
問題不在於我最初認為的轉換流。 只是缺少有關如何在WinRT中完成文件處理的知識(我認為Microsoft的文檔確實很糟糕)。
最后,在我的同事的幫助下,嘗試了幾種方法,最終得到以下結果:
public async Task SaveStreamToFile(Stream stream, string filePath, IProgress<long> progress )
{
var folder = await StorageFolder.GetFolderFromPathAsync(Path.GetDirectoryName(filePath));
var fileName = Path.GetFileName(filePath);
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
var istream = stream.AsInputStream();
using (var reader = new DataReader(istream))
{
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter writer = new DataWriter(outputStream))
{
long writtenBytes = 0;
const int bufferSize = 8192;
uint loadedBytes = 0;
while ((loadedBytes = (await reader.LoadAsync(bufferSize))) > 0) //!!!
{
IBuffer buffer = reader.ReadBuffer(loadedBytes);
writer.WriteBuffer(buffer);
uint tmpWritten = await writer.StoreAsync(); //!!!
writtenBytes += tmpWritten;
progress.Report(writtenBytes);
}
}
}
}
}
}
我希望看到一些更簡單的實現,但這可行。 問題在於缺少LoadAsync
(似乎必須調用它),並且在寫操作期間必須調用StoreAsync
才能提交數據(刷新不足)。
希望對您有所幫助。
我建議不要使用這種代碼,而應利用Windows Runtime Interop擴展方法 。 這將產生更整潔,更易讀的代碼,例如:
private async Task CopyToTempFile(Stream stream, string temporaryFileName) {
var file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(temporaryFileName, CreationCollisionOption.ReplaceExisting);
using (var outputstream = await file.OpenStreamForWriteAsync()) {
await stream.CopyToAsync(outputstream);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.