C# 我可以从文件.OpenStreamForWriteAsync()获取文件.OpenStreamForReadAsync()吗?
我仍在学习读/写文件流的诀窍,希望有人能帮助我,如果我所寻找的是可行的 下面的代码进行WebApi调用(注意第2行的C# 我可以从文件.OpenStreamForWriteAsync()获取文件.OpenStreamForReadAsync()吗?,c#,windows-runtime,uwp,storagefile,C#,Windows Runtime,Uwp,Storagefile,我仍在学习读/写文件流的诀窍,希望有人能帮助我,如果我所寻找的是可行的 下面的代码进行WebApi调用(注意第2行的GetAsync())以获取图像文件Id,并使用计算出的Md5Hash将下载的文件保存到数据库中。代码运行良好,但为了提高效率,我想知道是否可以从文件.OpenStreamForWriteAsync()中获取文件.OpenStreamForReadAsync()(即使不确定这是否可行,但我可以看到一些在流上运行的扩展方法,但到目前为止我所做的尝试都没有成功)。如果这是可能的,我可以
GetAsync()
)以获取图像文件Id,并使用计算出的Md5Hash将下载的文件保存到数据库中。代码运行良好,但为了提高效率,我想知道是否可以从文件.OpenStreamForWriteAsync()
中获取文件.OpenStreamForReadAsync()
(即使不确定这是否可行,但我可以看到一些在流上运行的扩展方法,但到目前为止我所做的尝试都没有成功)。如果这是可能的,我可以通过使用(var fileStream=await file.OpenStreamForWriteAsync()){…}块在中调用GetMD5Hash()方法来避免保存文件并再次打开它
我是否可以使用Utils.GetMD5Hash(stream)的等价物代码>,如下所示,在使用
块外部,在块内部,目的是避免在使用
块外部打开文件
var client = new HttpClient();
var response = await client.GetAsync(new Uri($"{url}{imageId}")); // call to WebApi; url and imageId defined earlier
if (response.IsSuccessStatusCode)
{
using (var contentStream = await response.Content.ReadAsInputStreamAsync())
{
var stream = contentStream.AsStreamForRead();
var file = await imagesFolder.CreateFileAsync(imageFileName, CreationCollisionOption.ReplaceExisting);
using (var fileStream = await file.OpenStreamForWriteAsync())
{
await stream.CopyToAsync(fileStream, 4096);
// >>>> At this point, from the Write fileStream, can I get the equivalent of file.OpenStreamForReadAsync() ??
}
var stream = await file.OpenStreamForReadAsync();
string md5Hash = await Utils.GetMD5Hash(stream);
await AddImageToDataBase(file, md5Hash);
}
}
MemoryStream
是读/写的,因此,如果您只想计算散列,那么类似这样的操作应该可以实现:
var stream = contentStream.AsStreamForRead();
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
string md5Hash = await Utils.GetMD5Hash(ms);
}
但是,由于您仍然希望保存该文件(毕竟它已传递到AddImageToDataBase
),请考虑
- 保存到
MemoryStream
- 重置内存流
- 将内存流复制到文件流
- 重置内存流
- 计算散列
不过,我建议您进行性能测量。操作系统会缓存文件I/O,因此不太可能需要进行物理磁盘读取来计算散列。性能提升可能不是您想象的那样。内存流是读/写的,因此,如果您只想计算散列,类似这样的操作应该可以做到:
var stream = contentStream.AsStreamForRead();
using (var ms = new MemoryStream())
{
stream.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
string md5Hash = await Utils.GetMD5Hash(ms);
}
但是,由于您仍然希望保存该文件(毕竟它已传递到AddImageToDataBase
),请考虑
- 保存到
MemoryStream
- 重置内存流
- 将内存流复制到文件流
- 重置内存流
- 计算散列
不过,我建议您进行性能测量。操作系统会缓存文件I/O,因此不太可能需要进行物理磁盘读取来计算散列。性能提升可能不是您想象的那样。以下是使用MemoryStream
的完整答案,正如Petter Hesselberg在其答案中所建议的那样。注意我必须遇到的几个棘手的情况,以完成我想做的事情:(1)确保fileStream
可以通过使用块进行一次性处理,以及(2)确保MemoryStream
设置为以ms.Seek开始(0,请参见Korigin.Begin)代码>在使用它之前,对于要保存的文件和为计算MD5Hash而移交的MemoryStream对象
var client = new HttpClient();
var response = await client.GetAsync(new Uri($"{url}{imageId}")); // call to WebApi; url and imageId defined earlier
if (response.IsSuccessStatusCode)
{
using (var contentStream = await response.Content.ReadAsInputStreamAsync())
{
var stream = contentStream.AsStreamForRead();
var file = await imagesFolder.CreateFileAsync(imageFileName, CreationCollisionOption.ReplaceExisting);
using (MemoryStream ms = new MemoryStream())
{
await stream.CopyToAsync(ms);
using (var fileStream = await file.OpenStreamForWriteAsync())
{
ms.Seek(0, SeekOrigin.Begin);
await ms.CopyToAsync(fileStream);
ms.Seek(0, SeekOrigin.Begin); // rewind for next use below
}
string md5Hash = await Utils.GetMD5Hash(ms);
await AddImageToDataBase(file, md5Hash);
}
}
}
下面是一个完整的答案,使用Petter Hesselberg在答案中建议的MemoryStream
。注意我必须遇到的几个棘手的情况,以完成我想做的事情:(1)确保fileStream
可以通过使用块进行一次性处理,以及(2)确保MemoryStream
设置为以ms.Seek开始(0,请参见Korigin.Begin)代码>在使用它之前,对于要保存的文件和为计算MD5Hash而移交的MemoryStream对象
var client = new HttpClient();
var response = await client.GetAsync(new Uri($"{url}{imageId}")); // call to WebApi; url and imageId defined earlier
if (response.IsSuccessStatusCode)
{
using (var contentStream = await response.Content.ReadAsInputStreamAsync())
{
var stream = contentStream.AsStreamForRead();
var file = await imagesFolder.CreateFileAsync(imageFileName, CreationCollisionOption.ReplaceExisting);
using (MemoryStream ms = new MemoryStream())
{
await stream.CopyToAsync(ms);
using (var fileStream = await file.OpenStreamForWriteAsync())
{
ms.Seek(0, SeekOrigin.Begin);
await ms.CopyToAsync(fileStream);
ms.Seek(0, SeekOrigin.Begin); // rewind for next use below
}
string md5Hash = await Utils.GetMD5Hash(ms);
await AddImageToDataBase(file, md5Hash);
}
}
}
你让我走上了正轨,谢谢。我发布了一个完整的答案。你让我走上了正确的轨道,谢谢。我发布了一个完整的答案。出于好奇,您是否尝试过任何性能测量?我会这样做并报告。我现在被别的事情打断了。出于好奇,你有没有尝试过任何性能测量?我会这样做并报告。此刻我被别的事情打断了。