Разделение файла, сопоставленного с памятью, на два фрагмента данных в C#C#

Место общения программистов C#
Ответить
Anonymous
 Разделение файла, сопоставленного с памятью, на два фрагмента данных в C#

Сообщение Anonymous »

Я пытаюсь создать MemoryMappedFile с двумя методами доступа к представлению, каждый из которых имеет доступ к различным областям этой общей памяти.
Это упрощенная версия того, что я делаю: р>
const int block1Size = 20;
const int block2Size = 10;
// create a shared memory region for the 2 blocks of data
MemoryMappedFile sharedFile = MemoryMappedFile.CreateNew("dummy_host_name", block1Size + block2Size);

// create an accessor for each memory block
// first block starts at index 0 and has 20 bytes
MemoryMappedViewAccessor block1Accessor = sharedFile.CreateViewAccessor(0, block1Size);
// second block starts at the and of the first block and has 10 bytes
MemoryMappedViewAccessor block2Accessor = sharedFile.CreateViewAccessor(block1Size, block2Size);

На первый взгляд кажется, что это работает так, как ожидалось: оба средства доступа к представлению памяти дают разные адреса памяти:
byte* block1 = null;
byte* block2 = null;
block1Accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref block1);
block2Accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref block2);
Console.WriteLine($"Block1 address: {(long)block1:X}");
Console.WriteLine($"Block2 address: {(long)block2:X}");


Адрес блока 1: 178823B0000

Адрес блока 2: 178823C0000

Но когда я пытаюсь записать в эти блоки памяти, кажется, что они и пишут, и читают по одному и тому же адресу памяти.
Например, когда я пытаюсь скопировать последовательность байтов в первый блок памяти, он также копирует эту последовательность во второй блок памяти:

// data before copying
// first block: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
// second block: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
fixed (byte* sourcePointer = sequenceByteArray)
{
Buffer.MemoryCopy(sourcePointer, block1, block1size, block1size);
}
// data after copying
// first block: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
// second block: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Когда я пишу во второй блок памяти, возникают те же проблемы.
Я не уверен, что здесь происходит, указатели обращаются разные, создание средства доступа к представлению кажется нормальным (если я не неправильно понял первый параметр, называемый offset). У меня нет идей.
Вот весь тестовый код консоли:< /p>
using System.IO.MemoryMappedFiles;

const int block1Size = 20;
const int block2Size = 10;
// create a shared memory region for the 2 blocks of data
MemoryMappedFile sharedFile = MemoryMappedFile.CreateNew("dummy_host_name", block1Size + block2Size);

// create an accessor for each memory block
// first block starts at index 0 and has 20 bytes
MemoryMappedViewAccessor block1Accessor = sharedFile.CreateViewAccessor(0, block1Size);
// second block starts at the and of the first block and has 10 bytes
MemoryMappedViewAccessor block2Accessor = sharedFile.CreateViewAccessor(block1Size, block2Size);

unsafe
{
byte* block1 = null;
byte* block2 = null;
// acquire pointers for each block
block1Accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref block1);
block2Accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref block2);
Console.WriteLine($"Block1 address: {(long)block1:X}");
Console.WriteLine($"Block2 address: {(long)block2:X}");

// clear garbage data
Copy(CreateZeros(block1Size), block1);
Copy(CreateZeros(block2Size), block2);
PrintData(block1, block2);

// write a sequence of 1 to 20 into the first memory block
byte[] firstDataInput = Enumerable.Range(1, block1Size).Select(i => (byte)i).ToArray();
Copy(firstDataInput, block1);
PrintData(block1, block2);

// write a sequence of 21 to 30 into the second memory block
byte[] secondDataInput = Enumerable.Range(block1Size + 1, block2Size).Select(i => (byte)i).ToArray();
Copy(secondDataInput, block2);
PrintData(block1, block2);
}

static unsafe string ToStr(byte* data, int length)
{
Span buffer = new Span(data, length);
return string.Join(", ", buffer.ToArray());
}

static unsafe void Copy(byte[] source, byte* destination)
{
fixed (byte* sourcePointer = source)
{
Buffer.MemoryCopy(sourcePointer, destination, source.Length, source.Length);
}
}

static unsafe byte[] CreateZeros(int size)
{
byte[] zeros = new byte[size];
Array.Fill(zeros, 0);
return zeros;
}

static unsafe void PrintData(byte* block1Data, byte* block2Data)
{
string firstDataStr = ToStr(block1Data, block1Size);
string secondDataStr = ToStr(block2Data, block2Size);

Console.WriteLine("first block: " + firstDataStr);
Console.WriteLine("second block: " + secondDataStr);
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... in-c-sharp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»