2013-11-26 111 views
0

我用4個線程將數據寫入文件。每個線程使用MMF來編寫文件的一部分。 當我用Notpad ++打開文件時,它總是在文件的一部分之間顯示空字節。使用內存映射文件時刪除空字節

線程1將1個寫入 線程2寫入12 線程3寫入123 螺紋4寫入1234

其結果將是這樣的:1Nul12Nul123Nul1234Nul

MMF需要2個字節寫入 「1」字符,但實際上「1」字符只有一個字節。

如果我將1字節設置爲MMF,它將拋出:訪問器中沒有足夠的字節在此位置寫入。

如何刪除這些空字節?

更新代碼: 我只使用2個線程以方便查看。

static void Main(string[] args) 
    { 
     File.Delete(@"C:\abc.txt"); 

     CancellationTokenSource tokenSource = new CancellationTokenSource(); 
     CancellationToken cancellationToken = tokenSource.Token; 

     // Write data to file using MMF. 
     Task<int>[] tasks = new Task<int>[2]; 
     tasks[0] = new Task<int>(() => F1(0, 2, "1", cancellationToken), cancellationToken); 
     tasks[1] = new Task<int>(() => F2(2,4, "12", cancellationToken), cancellationToken); 

     // Create MMF File. 
     MemoryMappedFileSecurity CustomSecurity = new MemoryMappedFileSecurity(); 

     MemoryMappedFile MemoryMapped = MemoryMappedFile.CreateFromFile(

       new FileStream(@"C:\abc.txt", FileMode.OpenOrCreate), 
       "MapAbcFile",// Name 

       20,         // Size 

       MemoryMappedFileAccess.ReadWrite,    // Access type 

       null,       // You can customize the security 

       HandleInheritability.None 
       , false);    // Inherit to child process 



     try 
     { 
      ParallelOptions op = new ParallelOptions(); 
      op.CancellationToken = tokenSource.Token; 
      Parallel.ForEach(tasks, op, t => 
      { 
       try 
       { 
        t.Start(); 
       } 
       catch (Exception) 
       { 

        tokenSource.Cancel(); 
       } 

      }); 

      // Wait for all the tasks to finish. 
      Task.WaitAll(tasks, cancellationToken); 

      Console.WriteLine("Done!"); 
     } 
     catch (OperationCanceledException) 
     { 
      Console.WriteLine("Cancelled!"); 
     } 
     catch (AggregateException ae) 
     { 
      //tokenSource.Cancel(); 

      Console.WriteLine("AggregateException!"); 
      // Assume we know what's going on with this particular exception. 
      // Rethrow anything else. AggregateException.Handle provides 
      // another way to express this. See later example. 
      foreach (var ie in ae.InnerExceptions) 
      { 
       Console.WriteLine(ie.Message); 
      } 
     } 

     MemoryMapped.Dispose(); 

    } 

    private static int F1(long offset, long size, string firstName, CancellationToken cancellationToken) 
    { 
     Console.WriteLine(string.Format("ManagedThreadId(F1): {0} - {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToLongTimeString())); 
     MemoryMappedFile MemoryMapped = MemoryMappedFile.OpenExisting("MapAbcFile"); 
     MemoryMappedViewAccessor WriteFirstPart = MemoryMapped.CreateViewAccessor(offset, size, MemoryMappedFileAccess.ReadWrite); 
     int i = 0; 

     foreach (char item in firstName.ToCharArray()) 
     { 
      WriteFirstPart.Write(i, item); 
      i++; 
     } 

     WriteFirstPart.Dispose(); 
     return 1; 
    } 
    private static int F2(long offset, long size, string lastName, CancellationToken cancellationToken) 
    { 
     Console.WriteLine(string.Format("ManagedThreadId(F2): {0} - {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToLongTimeString())); 

     MemoryMappedFile MemoryMapped = MemoryMappedFile.OpenExisting("MapAbcFile"); 
     MemoryMappedViewAccessor WriteFirstPart = MemoryMapped.CreateViewAccessor(offset, size, MemoryMappedFileAccess.ReadWrite); 
     int i = 0; 
     foreach (char item in lastName.ToCharArray()) 
     { 
      WriteFirstPart.Write(i, item); 
      i++; 
     } 
     WriteFirstPart.Dispose(); 

     return 1; 
    } 
+0

你能告訴我們你用來寫字節的代碼嗎? – rhughes

+1

'你有什麼想法嗎?'不是一個真正的問題。除此之外,這裏沒有問題。 –

+0

謝謝Dan-o。我更新了我的問題和代碼。 – user3003756

回答

2

你的錯誤是在這裏:

,但實際上 「1」 字只有一個字節。

然而,一個Char實際上定義爲:

表示一個字符作爲UTF-16代碼單元。

UTF-16代碼單元佔用兩個字節。

如果你想有一個1只佔用一個字節,那麼你需要使用的東西從System.Text.Encoding類使用ASCII說或UTF-8,或者一些其他的編碼在字符1佔用一個字節。例如。

foreach (byte item in System.Text.Encoding.UTF8.GetBytes(firstName)) 
{ 
    WriteFirstPart.Write(i, item); 
    i++; 
} 
+0

非常感謝@Damien_The_Unbeliever。你是對的。我做的。 – user3003756