【问题标题】:how to write lengthy string in memory mapped file?如何在内存映射文件中写入冗长的字符串?
【发布时间】:2019-01-24 14:10:28
【问题描述】:

我在对象列表中有数据列表,如下所示:

price:10, volumne:100, timestamp:1253568545
price:8, volumne:15, timestamp:4564546584545
price:68, volumne:846, timestamp:3548432545

所以现在我想将这些数据写入内存映射文件,就像我在这里写的一样。就像新行中的每个新符号信息一样。那么该怎么做呢?我在下面提到了我的代码,所以请帮我解决这个问题。

using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(@"D:\data.txt", System.IO.FileMode.OpenOrCreate, "map1", 1000))
{
   using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor())
   {
     foreach (var item in data.ticks)
     {
       byte[] data1 = Encoding.UTF8.GetBytes(item.t.ToString() + "," + item.p.ToString() + "," + item.s.ToString());
       accessor.WriteArray(0, data1, 0, data1.Length);
      }
    }
}```

In final I need a result like below so please help for solve it:
10,100,1253568545
8,15,4564546584545
68,846,3548432545


【问题讨论】:

    标签: c# memory-mapped-files memory-mapping


    【解决方案1】:

    .WriteArray() 方法的第一个参数是视图中它必须开始写入的相对位置。每当您写了一些东西时,您都必须根据写入的字节相应地增加该光标。如果要写入的字节加上当前位置超过当前窗口大小,则必须在所需位置创建一个新视图。这是一个例子:

    var items = Enumerable.Range(1, 80).Select(i => new { Id = Guid.NewGuid(), Name = $"Item {i}" }).ToList();
    
    using (var file = MemoryMappedFile.CreateFromFile(@"D:\data.txt", System.IO.FileMode.OpenOrCreate, "myMap", 4096))
    {
        MemoryMappedViewAccessor accessor = null;
        // Small window size to enforce roll-over for testing.
        var windowSize = 100;
        var absolutePosition = 0;
        var relativePosition = 0;
    
        try
        {
            accessor = file.CreateViewAccessor(absolutePosition, windowSize, MemoryMappedFileAccess.ReadWrite);
    
            foreach (var item in items)
            {
                var value = $"{item.Id},{item.Name}{Environment.NewLine}";
                var bytes = Encoding.UTF8.GetBytes(value);
    
                if (bytes.Length + relativePosition > windowSize)
                {
                    absolutePosition += relativePosition;
                    relativePosition = 0;
                    accessor.Dispose();
                    accessor = file.CreateViewAccessor(absolutePosition, windowSize, MemoryMappedFileAccess.ReadWrite);
                }
    
                accessor.WriteArray(relativePosition, bytes, 0, bytes.Length);
                relativePosition += bytes.Length;
            }
        }
        finally
        {
            if (accessor != null)
                accessor.Dispose();
        }
    }
    

    【讨论】:

    • 谢谢@Oliver。它工作正常。如果我使用简单的 txt 文件而不是内存映射文件,那么它会像内存映射文件一样工作。就像多个进程一次使用同一个文件一样,会导致行为不端吗?
    • @hardikdhankecha:我不完全理解你的问题。但是有可能多个进程写入同一个文件,因为您可以使用FileShare.ReadWrite 打开一个文件。但是要同步每个进程开始和停止写入的位置是非常非常非常困难的。相反,我会让每个进程写入自己的文件,最后将它们合并成一个大文件(如果需要)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 2021-02-08
    • 2016-01-08
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多