繁体   English   中英

在C#中缓存二进制文件

[英]Caching a binary file in C#

是否可以在.NET中缓存二进制文件并在缓存文件上执行普通文件操作?

执行此操作的方法是将FileStream的所有内容读入MemoryStream对象,然后将此对象用于I / O. 这两种类型都继承自Stream ,因此使用方式实际上是相同的。

这是一个例子:

private MemoryStream cachedStream;

public void CacheFile(string fileName)
{
    cachedStream = new MemoryStream(File.ReadAllBytes(fileName));
}

因此,当您想要缓存给定文件时,只需调用一次CacheFile方法,然后在代码中的任何其他位置使用cachedStream进行读取。 (实际文件一旦缓存其内容就会被关闭。)唯一要记住的是在完成后配置cachedStream

任何现代操作系统都内置了一个缓存系统,因此实际上无论何时与文件交互,您都要与文件的内存缓存进行交互。

在应用自定义缓存之前,您需要提出一个重要问题:当基础文件发生更改时会发生什么,因此我的缓存副本变得无效?

如果允许更改缓存副本,则可以进一步使问题复杂化,并且需要将更改保存回基础文件。

如果文件很小,只需按照另一个答案中的建议使用MemoryStream

如果需要将更改保存回文件,可以编写一个包装类,将所有内容转发到MemoryStream ,但另外还有一个IsDirty属性,只要执行写操作,它就会设置为true。 然后,您可以随时选择一些管理代码(在某个较大的事务结束时?),检查(IsDirty == true)并将新版本保存到磁盘。 这称为“延迟写入”缓存,因为修改是在内存中进行的,并且直到稍后才会实际保存。

如果你真的想让问题复杂化,或者你有一个非常大的文件,你可以实现自己的分页,在那里你选择一个缓冲区大小(可能是1 MB?)并保留少量固定大小的byte[]页面。 这次你的每个页面都有一个脏标志。 您将实现Stream方法,以便隐藏调用者的详细信息,并在必要时提取(或丢弃)页面缓冲区。

最后,如果您想要更轻松的生活,请尝试:

http://www.microsoft.com/Sqlserver/2005/en/us/compact.aspx

它允许您使用与SQL Server相同的SQL引擎,但是在文件上,所有内容都在您的进程内发生,而不是通过外部RDBMS服务器。 这可能会为您提供一种更简单的查询和更新文件的方法,并避免需要大量手写的持久性代码。

那么,您当然可以将文件读入byte []数组并开始处理它。 如果你想使用一个流你可以将你的FileStream复制到一个MemoryStream并开始使用它 - 如:

public static void CopyStream( Stream input, Stream output )
{
        var buffer = new byte[32768];
        int readBytes;
        while( ( readBytes = input.Read( buffer, 0, buffer.Length ) ) > 0 )
        {
                output.Write( buffer, 0, readBytes );
        }
}

如果您担心性能 - 通常,不同文件访问方法的内置机制应该足够了。

我不知道你究竟在做什么,但是我提出了这个建议(取决于你正在做什么,这可能是也可能不可行):

而不是只缓存文件的内容,为什么不把文件的内容放在一个很好的强类型的项集合中,然后缓存它? 它可能会使搜索项目更容易,更快,因为不涉及解析。

Lucene中有一个非常优雅的缓存系统,它将磁盘中的字节缓存到内存中并智能地更新商店等。您可能希望查看该代码以了解它们是如何操作的。 您可能还想阅读Microsoft SQL Server数据存储层 - 因为MSSQL团队非常关注一些更重要的实现细节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM