Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以从文件.OpenStreamForWriteAsync()获取文件.OpenStreamForReadAsync()吗?_C#_Windows Runtime_Uwp_Storagefile - Fatal编程技术网

C# 我可以从文件.OpenStreamForWriteAsync()获取文件.OpenStreamForReadAsync()吗?

C# 我可以从文件.OpenStreamForWriteAsync()获取文件.OpenStreamForReadAsync()吗?,c#,windows-runtime,uwp,storagefile,C#,Windows Runtime,Uwp,Storagefile,我仍在学习读/写文件流的诀窍,希望有人能帮助我,如果我所寻找的是可行的 下面的代码进行WebApi调用(注意第2行的GetAsync())以获取图像文件Id,并使用计算出的Md5Hash将下载的文件保存到数据库中。代码运行良好,但为了提高效率,我想知道是否可以从文件.OpenStreamForWriteAsync()中获取文件.OpenStreamForReadAsync()(即使不确定这是否可行,但我可以看到一些在流上运行的扩展方法,但到目前为止我所做的尝试都没有成功)。如果这是可能的,我可以

我仍在学习读/写文件流的诀窍,希望有人能帮助我,如果我所寻找的是可行的

下面的代码进行WebApi调用(注意第2行的
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);
        }
    }
}

你让我走上了正轨,谢谢。我发布了一个完整的答案。你让我走上了正确的轨道,谢谢。我发布了一个完整的答案。出于好奇,您是否尝试过任何性能测量?我会这样做并报告。我现在被别的事情打断了。出于好奇,你有没有尝试过任何性能测量?我会这样做并报告。此刻我被别的事情打断了。