2012-03-07 127 views
0

我正在使用streamwriter將字符串寫入流中。現在,當我從數據流中訪問數據時,會在內容結尾添加「\ 0 \ 0 \ 0」字符。我不得不追加流內容,所以它會產生問題,因爲我無法通過trim()或remove()或replace()方法刪除這些字符。StreamWriter中的特殊字符

下面是我使用的代碼:

用於書寫:

using (MemoryMappedViewStream stream = mmf.CreateViewStream()) 
{ 
    using (StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.Unicode)) 
    { 
     try 
     { 
      string[] files = System.IO.Directory.GetFiles(folderName, "*.*", System.IO.SearchOption.AllDirectories); 
      foreach (string str in files) 
      { 
       writer.WriteLine(str); 
      } 
      // writer.WriteLine(folderName); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine("Unable to write string. " + ex); 
     } 
     finally 
     { 
      mutex.ReleaseMutex(); 
      mutex.WaitOne(); 
     } 
    } 
} 

用於閱讀:

StringBuilder sb = new StringBuilder(); 
      string str = @"D:\Other Files\Test_Folder\New Text Document.txt"; 
using (var stream = mmf.CreateViewStream()) 
       { 
        System.IO.StreamReader reader = new System.IO.StreamReader(stream); 
        sb.Append(reader.ReadToEnd()); 
        sb.ToString().Trim('\0'); 
        sb.Append("\n" + str); 
       } 

我如何避免這種情況?

[UPDATES] 寫入

// Lock 
      bool mutexCreated; 
      Mutex mutex = new Mutex(true, fileName, out mutexCreated); 
      if (!mutexCreated) 
       mutex = new Mutex(true); 
      try 
      { 
       using (MemoryMappedViewStream stream = mmf.CreateViewStream()) 
       { 
        using (BinaryWriter writer = new BinaryWriter(stream)) 
        { 
         try 
         { 
          string[] files = System.IO.Directory.GetFiles(folderName, "*.*", System.IO.SearchOption.AllDirectories); 
          foreach (string str in files) 
          { 
           writer.Write(str); 
          } 
          writer.Flush(); 
         } 
         catch (Exception ex) 
         { 
          Debug.WriteLine("Unable to write string. " + ex); 
         } 
         finally 
         { 
          mutex.ReleaseMutex(); 
          mutex.WaitOne(); 
         } 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       Debug.WriteLine("Unable to monitor memory file. " + ex); 
      } 

StringBuilder sb = new StringBuilder(); 
      string str = @"D:\Other Files\Test_Folder\New Text Document.txt"; 
      try 
      { 
       using (var stream = mmf.CreateViewStream()) 
       { 
        System.IO.BinaryReader reader = new System.IO.BinaryReader(stream); 
        sb.Append(reader.ReadString()); 
        sb.Append("\n" + str); 
       } 
       using (var stream = mmf.CreateViewStream()) 
       { 
        System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream); 
        writer.Write(sb.ToString()); 
       } 
       using (var stream = mmf.CreateViewStream()) 
       { 
        System.IO.BinaryReader reader = new System.IO.BinaryReader(stream); 
        Console.WriteLine(reader.ReadString()); 
       } 
      } 
      catch (Exception ex) 
      { 
       Debug.WriteLine("Unable to monitor memory file. " + ex); 
      } 
+0

在完成寫入文件後,您是否嘗試過writer.Flush()? – GrandMasterFlush 2012-03-07 10:27:20

+0

不,讓我試試。 – 2012-03-07 10:27:57

+0

剛剛嘗試用writer.Flush(),但注意工作.. – 2012-03-07 10:30:12

回答

1

你一個MMF和的TextWriter/TextReader的組合,特別是ReadToEnd的()不是一個很好的匹配。

textReader需要底層文件的EOF概念,而MMF只是不以相同的方式提供。你會得到你的字符串填充\0\0...到MMF的容量。

,作爲一種可能的解決辦法:

  • 收集字符串StringBuilder中
  • 寫使用的BinaryWriter把它寫爲1串
  • 讀回用BinaryReader在。

另一種選擇是使用WriteLine/ReadLine並定義一些EOF標記(空行或特殊字符串)。

BinaryWriter會在字符串前添加長度前綴,以便讀者知道何時停止。

+0

當我嘗試使用ReadString()方法從BinaryReader讀取時,它只返回第一行。我如何從閱讀器中檢索所有數據? – 2012-03-07 11:58:15

+0

它應該返回整個字符串,包括''\ n''。檢查你的寫作代碼或發佈兩件。 – 2012-03-07 12:02:21

+0

我可以在哪裏發佈代碼? – 2012-03-07 12:05:44

3

沒有'\ 0'被StreamWriter追加。這些只是內存映射文件的內容,在你開始編寫之前就有。 StreamReader需要一個文件結束指示符來知道何時停止讀取。在該部分的大小之外沒有任何mmf。像傳遞給MemoryMappedFile.CreateNew(string,long)的第二個參數一樣。

或換句話說,您創建了一個太大而不適合流的mmf。那麼,當然,你沒有時間機器來猜測它有多大。你肯定需要做些什麼,修剪零不夠好。第二次寫出更短的流時出錯。讀者現在仍然會看到來自以前流內容的字節,它們不會爲零。

這是MMFS常見的頭痛,它們只是內存塊,流是一個非常糟糕的抽象。爲了獲得.NET的支持,花費了這麼長時間的一個重要原因之一,即使它們是一個非常核心的操作系統功能。您需要指針來映射mmf,但在託管語言中這種支持得不到很好的支持。

我沒有看到在這種情況下教StreamReader新技巧的好方法。將mmf中的字節複製到MemoryStream中可以解決這個問題,但是卻可以解決mmf的問題。

請考慮使用管道。

+0

感謝指向正確的方向。 – 2012-03-07 11:18:45