Question

I have a few methods which work with MemoryMappedFiles for writing/reading data. They work alright if I use simple string for file name, for example "file.mmf". However if I use full directory path the above mentioned exception is being thrown - Exception has been thrown by the target of an invocation. With inner exception - {"Could not find a part of the path."}. Here is how my method looks like:

public void WriteToFile(string fileName, string value)
{
    string newFileName = CombineDirectory(fileName);
    byte[] newValue = Encoding.UTF8.GetBytes(value);
    long capacity = newValue.Length + INT_MAXVALUE_TO_BYTEARRAY_LENGTH;

    using (var mmf = MemoryMappedFile.CreateFromFile(newFileName, FileMode.Create, newFileName, capacity))
    {
        using (var accesor = mmf.CreateViewAccessor())
        {
            byte[] newValueLength = BitConverter.GetBytes(value.Length);
            accesor.WriteArray(0, newValueLength, 0, newValueLength.Length);
            accesor.WriteArray(INT_MAXVALUE_TO_BYTEARRAY_LENGTH, newValue, 0, newValue.Length);
        }
    }
}

My path looks like this :

"C:\\Users\\MyUser\\Documents\\Visual Studio 2012.mmf"

And I am using

Path.Combine

The exception occurs on the first 'using' line. If I try to create a file using the same file path with

File.Create

the file is being created with no problem.

If anyone has any suggestions, that would be great.

Regards

Was it helpful?

Solution

You need to make sure that the mapName argument (i.e. the third argument in your call to CreateFromFile) is not identical to the file path. It will throw a PathNotFound exception if you do. Not really helpful in figuring out why it is failing, I agree.

So your options for choosing a map name value:

  • Generate some unique key, e.g. Guid.NewGuid().ToString()
  • Use a constant value, e.g. "MySpecialMapForThings"
  • Use some convention, e.g. generate a unique key that you also use for just the file name part of the mapped file.

An example for the last option:

public static Tuple<FileInfo, string> GenerateMapInfo(string mapDirectory, string fileExtension)
{
    var uniqueMapName = Guid.NewGuid().ToString();
    var fileName = Path.Combine(mapDirectory, Path.ChangeExtension(uniqueMapName, fileExtension));
    return Tuple.Create(new FileInfo(fileName), uniqueMapName);
}

public void WriteToFile(Tuple<FileInfo, string> mapInfo, string value)
{
    byte[] newValue = Encoding.UTF8.GetBytes(value);
    long capacity = newValue.Length + INT_MAXVALUE_TO_BYTEARRAY_LENGTH;

    using (var mmf = MemoryMappedFile.CreateFromFile(mapInfo.Item1.FullName, FileMode.Create, mapInfo.Item2, capacity))
    using (var accesor = mmf.CreateViewAccessor())
    {
        byte[] newValueLength = BitConverter.GetBytes(value.Length);
        accesor.WriteArray(0, newValueLength, 0, newValueLength.Length);
        accesor.WriteArray(INT_MAXVALUE_TO_BYTEARRAY_LENGTH, newValue, 0, newValue.Length);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top