StreamWriter中的特殊字符
本文关键字:特殊字符 StreamWriter | 更新日期: 2023-09-27 18:26:57
我正在使用streamwriter将字符串写入流中。现在,当我访问流中的数据时,它会在内容的末尾添加"''0''0''0"个字符。我必须附加流内容,所以这会产生问题,因为我无法通过trim()、remove()或replace()方法删除这些字符。
以下是我正在使用的代码:
写入:
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);
}
我该如何防止这种情况发生?
[更新]写入
// 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);
}
StreamWriter没有附加'''0'。这些只是内存映射文件的内容,在您开始编写之前存在的内容。StreamReader需要一个文件结束指示器来知道何时停止读取。mmf中没有任何超出节的大小的内容。类似于传递给MemoryMappedFile.CreateNew的第二个参数(字符串,长)。
或者换句话说,您创建的mmf太大,无法容纳流。当然,你没有时间机器来猜测它有多大。你肯定需要做点什么,修剪零还不够好。第二次编写较短的流时,就会出现错误。阅读器现在仍然可以看到以前流内容中的字节,它们不会为零。
在其他方面,这是mmfs常见的头痛问题,它们只是内存块,而流是一个非常糟糕的抽象。尽管mmfs是一个非常核心的操作系统功能,但它花了这么长时间才得到.NET的支持,这也是其中一个重要原因。您需要指针来映射mmf,而这在托管语言中并没有得到很好的支持。
在这种情况下,我看不出教StreamReader新技巧的好方法。将字节从mmf复制到MemoryStream中可以解决问题,但会破坏mmf的作用。
请考虑改用管道。
MMF和TextWriter/TextReader的组合,尤其是ReadToEnd(),不是很匹配。
textReader需要底层文件的EOF概念,而MMF则不以相同的方式提供EOF概念。你会得到你的字符串填充'0'0...
,直到MMF的容量。
作为一个可能的解决方案:
- 收集要在StringBuilder中写入的字符串
- 使用BinaryWriter将其写成1个字符串
- 用BinaryReader读回
另一种选择是使用WriteLine/ReadLine并定义一些EOF标记(空行或特殊字符串)。
BinaryWriter会在字符串前面加上一个长度前缀,以便阅读器知道何时停止。