Pergunta

É possível armazenar em cache um arquivo binário em .NET e fazer operações de arquivo normais no arquivo em cache?

Foi útil?

Solução

A maneira de fazer isso é ler todo o conteúdo do FileStream em um objeto MemoryStream, e, em seguida, usar esse objeto para E / S mais tarde. Ambos os tipos herdam Stream, de modo que o uso será efetivamente idênticas.

Aqui está um exemplo:

private MemoryStream cachedStream;

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

Então, basta chamar o método CacheFile uma vez quando você deseja armazenar em cache o arquivo dado, e, em seguida, em qualquer outro lugar em uso de código cachedStream para a leitura. (O arquivo real irá sido fechada assim que o seu conteúdo foi armazenado em cache.) A única coisa a lembrar é cachedStream dispor quando tiver terminado com ele.

Outras dicas

Qualquer sistema operacional moderno tem um sistema de cache embutido, então na verdade sempre que você interage com um arquivo, você está interagindo com um cache de memória do arquivo.

Antes de aplicar o cache de costume, você precisa perguntar a uma pergunta importante: o que acontece quando as mudanças de arquivos subjacentes, por isso a minha cópia em cache torna-se inválido

Você pode complicar ainda mais se a cópia em cache é permitida a mudança, e as mudanças precisam ser salvos de volta para o arquivo subjacente.

Se o arquivo é pequeno, é mais simples apenas para uso MemoryStream como sugerido em outra resposta.

Se você precisa para salvar alterações de volta para o arquivo, você poderia escrever uma classe wrapper que encaminha tudo para MemoryStream, mas além disso, tem uma propriedade IsDirty que ele define como verdadeiro sempre que uma operação de gravação é executada. Então você pode ter algum código de gestão que entra em ação sempre que você escolher (no final de alguma transação maior?), Verifica (IsDirty == true) e salva a nova versão para o disco. Isso é chamado de "preguiçoso write" caching, como as modificações são feitas na memória e não são realmente salvos até algum tempo mais tarde.

Se você realmente quer a questões complicar, ou você tem um arquivo muito grande, você poderia implementar sua própria paginação, onde você escolhe um tamanho de buffer (talvez 1 MB?) E mantenha um pequeno número de páginas byte[] desse tamanho fixo . Desta vez, você teria um sinalizador sujo para cada página. Você iria implementar os métodos do córrego para que eles esconder os detalhes do chamador, e puxar (ou descartar) buffers de página sempre que necessário.

Finalmente, se você quer uma vida mais fácil, tente:

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

Ele permite que você use o mesmo motor SQL como SQL Server, mas em um arquivo, com tudo o que acontece dentro de seu processo em vez de através de um servidor RDBMS externo. Isso provavelmente vai lhe dar uma maneira muito mais simples de consultar e atualizar seu arquivo, e evitar a necessidade de um monte de código de persistência escrita à mão.

Bem, você pode, naturalmente, ler o arquivo em uma matriz byte [] e começar a trabalhar nele. E se você quiser usar um fluxo você pode copiar sua FileStream em um MemoryStream e começar a trabalhar com ele - como:

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 );
        }
}

Se você está preocupado com o desempenho -. Bem, normalmente o build-in mecanismos dos diferentes métodos de acesso ao arquivo deve ser suficiente

Eu não sei exatamente o que você está fazendo, mas eu ofereço esta sugestão (que pode ou não ser viável dependendo do que você está fazendo):

Em vez de apenas cache o conteúdo do arquivo, por que não colocar o conteúdo do arquivo em um agradável fortemente coleção digitado de itens, e em seguida, cache que? Ele provavelmente vai tornar a busca por itens um pouco mais fácil e mais rápido, pois não há nenhuma análise envolvida.

Há um sistema de cache muito elegante em Lucene que caches bytes do disco para a memória e inteligentemente atualiza a loja etc. Você pode querer ter um olhar para esse código para ter uma idéia de como eles fazem isso. Você também pode querer ler-se sobre a camada de armazenamento de dados Microsoft SQL Server - como a equipe MSSQL é muito próximo sobre alguns dos detalhes mais cruciais de implementação

.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top