搜索行时覆盖 txt 文件中的行
Overwriting lines in a txt file while searching for the lines
我正在使用 C# 开发视频游戏。我在 .txt 文件中有一个用户列表,其中包含他们的硬币数量,我希望在他们保存时覆盖他们的数量。我不知道如何在没有 "file already being used" 异常的情况下在 SteamReader 中使用 SteamWriter。基本上,我需要搜索用户名,如果找到,则用相同的用户名和新的硬币数量覆盖现有行。所有硬币数量均为“0000”格式(0010、0199 等),因此我可以使用 Substring 和 length 轻松查找和加载硬币数量。
这是我尝试使用的代码:
StreamReader sr = new StreamReader("C:\FakeFilePath");
String line;
try
{
line = sr.ReadLine();
while (line != null)
{
if (line.Contains(users[m.GetInt(0)].username))
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\FakeFilePath", false))
{
file.WriteLine("\n" + users[m.GetInt(0)].username + " " + (users[m.GetInt(0)].rupees).ToString("D4"));
file.Close();
}
}
line = sr.ReadLine();
}
}
finally
{
sr.Close();
}
非常感谢任何帮助。
谢谢,
迪斯马斯盖伊
您可能应该按照评论者 Jonesy 的建议,通过简单地重写整个文件来做到这一点。文本文件可能相对较小,可能小于单个磁盘块(通常大小为 4K,但可能因文件系统配置而异),并且重写整个文件实际上与覆盖特定位置一样快。
如果您确实坚持只尝试覆盖特定位置,则需要一种可靠的方法来计算要写入的文件中的位置,然后您需要在写入之前设置 StreamWriter.BaseStream
对象的位置新数据。您还需要使用 read/write 访问权限打开文件一次,或者打开一次文件进行读取以找到位置,然后在再次打开文件进行写入之前将其关闭。
计算文件中位置的最简单方法是采用固定大小的字符编码,例如ASCII 或 UTF16。对于 ASCII,文件中的偏移量(以字节为单位)将与字符数相同;使用UTF16,它将是字符数的两倍。
注意每一行也必须有固定的长度;也就是说,您将用户名以及硬币数量存储在该行的固定宽度字段中。所以文件可能看起来像这样:
Username1 0001
User24 0117
SallyDoe999 0037
注意:上面每行20个字符:名字14个字符,硬币数4个字符,当然还有换行的两个字符。
例如,假设您将数据存储为 ASCII:
string fileName = "C:\FakeFilePath";
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
using (StreamReader sr = new StreamReader(stream, Encoding.ASCII))
using (StreamWriter writer = new StreamWriter(stream, Encoding.ASCII))
{
int lineCount = 0;
String line;
while ((line = sr.ReadLine()) != null)
{
if (line.Contains(users[m.GetInt(0)].username))
{
// Offset is the offset of the line itself, plus
// the length of the name field (the name field doesn't
// need to be written because it's already the right
// value!)
int byteOffset = (lineCount * 20) + 14;
writer.BaseStream.Position = byteOffset;
writer.Write(users[m.GetInt(0)].rupees.ToString("D4"));
break;
}
lineCount++;
}
}
如您所见,这需要付出很多努力,尤其是当您不得不更改文件格式时。那里有很多挑剔的 "has to be just right" 代码,它当然会大大限制您在文件格式方面的选择。我希望您能看到在需要更改时将整个文件重新写出来的智慧。 :)
我正在使用 C# 开发视频游戏。我在 .txt 文件中有一个用户列表,其中包含他们的硬币数量,我希望在他们保存时覆盖他们的数量。我不知道如何在没有 "file already being used" 异常的情况下在 SteamReader 中使用 SteamWriter。基本上,我需要搜索用户名,如果找到,则用相同的用户名和新的硬币数量覆盖现有行。所有硬币数量均为“0000”格式(0010、0199 等),因此我可以使用 Substring 和 length 轻松查找和加载硬币数量。
这是我尝试使用的代码:
StreamReader sr = new StreamReader("C:\FakeFilePath");
String line;
try
{
line = sr.ReadLine();
while (line != null)
{
if (line.Contains(users[m.GetInt(0)].username))
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\FakeFilePath", false))
{
file.WriteLine("\n" + users[m.GetInt(0)].username + " " + (users[m.GetInt(0)].rupees).ToString("D4"));
file.Close();
}
}
line = sr.ReadLine();
}
}
finally
{
sr.Close();
}
非常感谢任何帮助。
谢谢, 迪斯马斯盖伊
您可能应该按照评论者 Jonesy 的建议,通过简单地重写整个文件来做到这一点。文本文件可能相对较小,可能小于单个磁盘块(通常大小为 4K,但可能因文件系统配置而异),并且重写整个文件实际上与覆盖特定位置一样快。
如果您确实坚持只尝试覆盖特定位置,则需要一种可靠的方法来计算要写入的文件中的位置,然后您需要在写入之前设置 StreamWriter.BaseStream
对象的位置新数据。您还需要使用 read/write 访问权限打开文件一次,或者打开一次文件进行读取以找到位置,然后在再次打开文件进行写入之前将其关闭。
计算文件中位置的最简单方法是采用固定大小的字符编码,例如ASCII 或 UTF16。对于 ASCII,文件中的偏移量(以字节为单位)将与字符数相同;使用UTF16,它将是字符数的两倍。
注意每一行也必须有固定的长度;也就是说,您将用户名以及硬币数量存储在该行的固定宽度字段中。所以文件可能看起来像这样:
Username1 0001
User24 0117
SallyDoe999 0037
注意:上面每行20个字符:名字14个字符,硬币数4个字符,当然还有换行的两个字符。
例如,假设您将数据存储为 ASCII:
string fileName = "C:\FakeFilePath";
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
using (StreamReader sr = new StreamReader(stream, Encoding.ASCII))
using (StreamWriter writer = new StreamWriter(stream, Encoding.ASCII))
{
int lineCount = 0;
String line;
while ((line = sr.ReadLine()) != null)
{
if (line.Contains(users[m.GetInt(0)].username))
{
// Offset is the offset of the line itself, plus
// the length of the name field (the name field doesn't
// need to be written because it's already the right
// value!)
int byteOffset = (lineCount * 20) + 14;
writer.BaseStream.Position = byteOffset;
writer.Write(users[m.GetInt(0)].rupees.ToString("D4"));
break;
}
lineCount++;
}
}
如您所见,这需要付出很多努力,尤其是当您不得不更改文件格式时。那里有很多挑剔的 "has to be just right" 代码,它当然会大大限制您在文件格式方面的选择。我希望您能看到在需要更改时将整个文件重新写出来的智慧。 :)