Промежуточная среда 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;
}