MemoryMappedFile:无法找到指定的文件
MemoryMappedFile: Unable to find the specified file
我无法使 MemoryMappedFile 模式正常工作。我有一个包含 25 excel 个电子表格的目录,我想使用 MemoryMappedFile 加载这些电子表格。 MemoryMappedFile.CreateFromFile 工作正常,但是当我调用 MemoryMappedFile.OpenExisting(lender) 时,它会读取前 3 个文件,然后在第 4 次尝试时,失败并出现异常:
Unable to find the specified file.
public static void Main()
{
var files = System.IO.Directory.EnumerateFiles(@"lendersheets", "*.xls*").ToList();
foreach (var file in files)
{
var lender = System.IO.Path.GetFileNameWithoutExtension(file);
MemoryMappedFile.CreateFromFile(file, FileMode.Open, lender);
}
foreach (var file in files)
{
var lender = System.IO.Path.GetFileNameWithoutExtension(file);
using (var mmfExisting = MemoryMappedFile.OpenExisting(lender))
{
var stream = mmfExisting.CreateViewStream();
if (stream.CanRead && stream.CanWrite)
{
LoadFromStream(stream);
}
}
}
}
更新:
我注意到当我删除 LoadFromStream 方法调用时,异常不再发生。这是 LoadFromStream 的逻辑:
private static object LoadFromStream(Stream stream)
{
hssfwb = new HSSFWorkbook(stream);
evaluator = new HSSFFormulaEvaluator(hssfwb);
return hssfwb;
}
我最终做了以下事情。我有一个内存中所有文件集合的单例实例。当我需要使用内存中的特定文件进行计算时,我会创建一个新的内存流实例:
private static readonly Dictionary<string, MemoryStream> _lenderPolicyFileStreams = new Dictionary<string, MemoryStream>();
private static void CreateLenderPolicyFileStreams()
{
string appDataPath = HostingEnvironment.MapPath("~/App_Data");
var files = Directory.EnumerateFiles(appDataPath, "*.xls*").ToList();
foreach (var file in files)
{
var lenderName = Path.GetFileNameWithoutExtension(file);
// Create a file stream
var bytes = File.ReadAllBytes(file);
var stream = new MemoryStream(bytes);
// Add file stream to singleton collection
if (lenderName != null)
_lenderPolicyFileStreams.Add(lenderName, stream);
}
}
public static Stream GetMemoryStreamByLenderName(string lender)
{
MemoryStream fetchedStream;
_lenderPolicyFileStreams.TryGetValue(lender, out fetchedStream);
if (fetchedStream == null)
throw new Exception("Cannot find specified file stream by lender name");
var clone = CloneStream(fetchedStream);
return clone;
}
private static MemoryStream CloneStream(MemoryStream fileStream)
{
var memoryStream = new MemoryStream();
fileStream.Position = 0;
fileStream.CopyTo(memoryStream);
memoryStream.Position = 0;
return memoryStream;
}
我无法使 MemoryMappedFile 模式正常工作。我有一个包含 25 excel 个电子表格的目录,我想使用 MemoryMappedFile 加载这些电子表格。 MemoryMappedFile.CreateFromFile 工作正常,但是当我调用 MemoryMappedFile.OpenExisting(lender) 时,它会读取前 3 个文件,然后在第 4 次尝试时,失败并出现异常:
Unable to find the specified file.
public static void Main()
{
var files = System.IO.Directory.EnumerateFiles(@"lendersheets", "*.xls*").ToList();
foreach (var file in files)
{
var lender = System.IO.Path.GetFileNameWithoutExtension(file);
MemoryMappedFile.CreateFromFile(file, FileMode.Open, lender);
}
foreach (var file in files)
{
var lender = System.IO.Path.GetFileNameWithoutExtension(file);
using (var mmfExisting = MemoryMappedFile.OpenExisting(lender))
{
var stream = mmfExisting.CreateViewStream();
if (stream.CanRead && stream.CanWrite)
{
LoadFromStream(stream);
}
}
}
}
更新:
我注意到当我删除 LoadFromStream 方法调用时,异常不再发生。这是 LoadFromStream 的逻辑:
private static object LoadFromStream(Stream stream)
{
hssfwb = new HSSFWorkbook(stream);
evaluator = new HSSFFormulaEvaluator(hssfwb);
return hssfwb;
}
我最终做了以下事情。我有一个内存中所有文件集合的单例实例。当我需要使用内存中的特定文件进行计算时,我会创建一个新的内存流实例:
private static readonly Dictionary<string, MemoryStream> _lenderPolicyFileStreams = new Dictionary<string, MemoryStream>();
private static void CreateLenderPolicyFileStreams()
{
string appDataPath = HostingEnvironment.MapPath("~/App_Data");
var files = Directory.EnumerateFiles(appDataPath, "*.xls*").ToList();
foreach (var file in files)
{
var lenderName = Path.GetFileNameWithoutExtension(file);
// Create a file stream
var bytes = File.ReadAllBytes(file);
var stream = new MemoryStream(bytes);
// Add file stream to singleton collection
if (lenderName != null)
_lenderPolicyFileStreams.Add(lenderName, stream);
}
}
public static Stream GetMemoryStreamByLenderName(string lender)
{
MemoryStream fetchedStream;
_lenderPolicyFileStreams.TryGetValue(lender, out fetchedStream);
if (fetchedStream == null)
throw new Exception("Cannot find specified file stream by lender name");
var clone = CloneStream(fetchedStream);
return clone;
}
private static MemoryStream CloneStream(MemoryStream fileStream)
{
var memoryStream = new MemoryStream();
fileStream.Position = 0;
fileStream.CopyTo(memoryStream);
memoryStream.Position = 0;
return memoryStream;
}