MemoryMappedFile:无法找到指定的文件

时间:2015-07-28 06:21:27

标签: c# memory-mapped-files

我无法使MemoryMappedFile模式生效。我有一个包含25个excel电子表格的目录,我想用MemoryMappedFile加载它。 MemoryMappedFile.CreateFromFile 工作得很好,但是当我调用 MemoryMappedFile.OpenExisting(贷方)时,它会读取前3个文件,然后在第4次尝试时失败,例外:

  

无法找到指定的文件。

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

1 个答案:

答案 0 :(得分:0)

我最终做了以下事情。我在Memory中有一个所有文件集合的单例实例。然后,当我需要在内存中使用特定文件进行计算时,我创建了一个新的内存流实例:

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