Россия, г. Москва |
Промежуточная среда COM+ и служба Enterprise Services
Класс StreamCache помогает организовать кеширование содержимого файлов, использующихся в транзакции.
public class StreamCache { private string fileName; private MemoryStream stream; public MemoryStream Stream { get { return stream;} } public string FileName { get { return fileName;} } public StreamCache(string streamFileName) { fileName = streamFileName; stream = new MemoryStream(); }
Метод Reopen при необходимости открывает повторно закрытый поток. Поскольку такая операция не поддерживается классом MemoryStream, то сначала в массив записывается все содержимое потока, затем создается новый поток, куда записываются сохраненные данные.
public void Reopen() { if (!stream.CanRead) { stream.Close(); byte[] buffer = stream.ToArray(); stream.Dispose(); stream = new MemoryStream(); stream.Write(buffer, 0, buffer.Length); stream.Seek(0, SeekOrigin.Begin); } } // Reopen()
При открытии файла для чтения вызывается метод Read, считывающий все содержимое файла в поток типа MemoryStream.
public void Read() { byte[] buffer = new byte[32*1024]; using (Stream inputStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { while (true) { int read = inputStream.Read(buffer, 0, buffer.Length); if (read <= 0) { break; } Stream.Write(buffer, 0, read); } } } // Read() } // StreamCache
Класс StreamCrm является менеджером ресурсов, используемым объектами COM+. Он является COM+ объектом, поэтому несколько участвующих в транзакции компонент COM+ могут работать с одним менеджером ресурсов данного типа. Менеджер содержит кеш для реализации отложенной до завершения транзакции записи в файл.
public class StreamCrm: ServicedComponent { private Dictionary<string, StreamCache> cache; public StreamCrm() { cache = new Dictionary<string, StreamCache>(); }
Метод StreamCrm.CheckCache проверяет, есть ли в кеше информация о данном файле. При отсутствии ее в кеше в случае открытия файла на чтение происходит считывания всего содержимого файла в кеш, в противном случае связанный с файлом поток открывается повторно вызовом метода StreamCache.Reopen.
private StreamCache CheckCache(string fileName, bool read) { StreamCache streamCache; string key = Path.GetFullPath(fileName).ToLower(); if (!cache.ContainsKey(key)) { streamCache = new StreamCache(fileName); cache.Add(key, streamCache); if (read) { streamCache.Read(); }; } else { streamCache = cache[key]; streamCache.Reopen(); }; return streamCache; }