StreamWriter中的特殊字符

时间:2012-03-07 10:24:06

标签: c# streamwriter

我正在使用streamwriter将字符串写入流。现在,当我从流中访问数据时,它会将“\ 0 \ 0 \ 0”字符添加到内容的末尾。我必须追加流内容,因此我不能通过trim()或remove()或replace()方法删除这些字符。

以下是我正在使用的代码:

FOR WRITING:

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();
        }
    }
}

FOR READING:

 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);
            }

2 个答案:

答案 0 :(得分:4)

没有'\ 0'被StreamWriter追加。这些只是内存映射文件的内容,是开始编写之前的内容。 StreamReader需要一个文件结束指示符来知道何时停止读取。除了 size 之外的mmf中没有任何内容。就像第二个参数一样,你传递给MemoryMappedFile.CreateNew(string,long)。

或者换句话说,您创建了一个太大而不适合流的mmf。嗯,当然,你没有时间机器来猜测它有多大。你肯定需要做些什么,修剪零点是不够的。第二次写一个更短的流时出错了。读者现在仍然可以看到前一个流内容中的字节,它们不会为零。

这是mmfs的常见问题,它们只是内存块,而流是一种非常糟糕的抽象。 mmfs得到.NET支持这么长时间的一个重要原因,即使它们是一个非常核心的操作系统功能。您需要指向映射mmf的指针,并且在托管语言中不能很好地支持。

在这种情况下,我没有看到教授StreamReader新技巧的好方法。将mmf中的字节复制到MemoryStream中可以解决问题,但是会破坏mmf的点。

考虑使用管道。

答案 1 :(得分:2)

MMF和TextWriter / TextReader的组合,特别是ReadToEnd()不是很好的匹配。

textReader需要底层文件的EOF概念,MMF不会以相同的方式提供它。您将使用\0\0...填充您的字符串,直到MMF的容量。

作为一种可能的解决办法:

  • 收集字符串以在StringBuilder中写入
  • 使用BinaryWriter将其写为1个字符串
  • 使用BinaryReader读回来。

另一个选择是使用WriteLine / ReadLine并定义一些EOF标记(空行或特殊字符串)。

BinaryWriter将为字符串添加长度前缀前缀,以便Reader知道何时停止。