我正在使用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);
}
答案 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的容量。
作为一种可能的解决办法:
另一个选择是使用WriteLine / ReadLine并定义一些EOF标记(空行或特殊字符串)。
BinaryWriter将为字符串添加长度前缀前缀,以便Reader知道何时停止。