C# 读取文件
我有两个功能:
public void SaveMap()
{
StreamWriter stream = new StreamWriter("file.txt");
for (int j = 0; j < GameConstants.MapMaxTilesX; j++)
{
for (int i = 0; i < GameConstants.MapMaxTilesY; i++)
{
stream.Write( map[j,i] );
}
}
stream.Close();
}
public void LoadMap()
{
StreamReader stream = new StreamReader("file.txt");
for (int j = 0; j < GameConstants.MapMaxTilesX; j++)
{
for (int i = 0; i < GameConstants.MapMaxTilesY; i++)
{
map[j, i] = (int)stream.Read();
}
}
stream.Close();
}
由于它正确保存数据,所以它不会读取数据。正在读取随机值(至少不是文件中的值)
我做错了什么?
I've got two functions:
public void SaveMap()
{
StreamWriter stream = new StreamWriter("file.txt");
for (int j = 0; j < GameConstants.MapMaxTilesX; j++)
{
for (int i = 0; i < GameConstants.MapMaxTilesY; i++)
{
stream.Write( map[j,i] );
}
}
stream.Close();
}
public void LoadMap()
{
StreamReader stream = new StreamReader("file.txt");
for (int j = 0; j < GameConstants.MapMaxTilesX; j++)
{
for (int i = 0; i < GameConstants.MapMaxTilesY; i++)
{
map[j, i] = (int)stream.Read();
}
}
stream.Close();
}
And as it saves data properly, it doesn't read it. Random values are being read ( at least not those which are in file )
What did I wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
即使
StreamReader.Read()
方法返回int
,它也不会从文件中读取int
。相反,它返回单个字符。该类型是int
的原因是它可以用 -1 标记文件结束条件。这是旧的 C 做事风格的延续。如果您想从文件中读取字符,您可以调用
Read()
并根据 -1 测试返回值。如果返回 -1 以外的值,则将其转换为char
。然后你将负责以有意义的方式将角色组合在一起。但还有更简单的方法可以完成您想要完成的任务!要执行您想做的操作,您必须以某种方式分隔整数值,然后解析文件中的字符串,或者改用 BinaryWriter/BinaryReader。
也许最简单的方法是每行放置一个值,如下所示:
如果您想最小化文件大小,那么我建议使用
BinaryWriter
写入每个 int,然后使用BinaryReader.ReadInt32()
方法。如果您这样做,那么该文件的长度将恰好是4 * GameConstants.MapMaxTilesX * GameConstants.MapMaxTilesY
字节长。另一种有趣的方法是将地图的每一行写在自己的行上,并用制表符
'\t'
分隔每一列。然后,您可以一次读回一行值,并使用 string.Split 分隔每行上的值。这种方法的优点是您可以在电子表格程序或文本编辑器中编辑文件。Even though the
StreamReader.Read()
method returns anint
, it doesn't read anint
from the file. Instead it returns a single character. The reason the type is anint
is so it can flag the end-of-file condition with a -1. This is a holdover from the old C style of doing things.If you wanted to read characters from a file, you could call
Read()
and test the return value against -1. If something other than -1 is returned, then cast that to achar
. Then you would be responsible for putting the characters together in a meaningful way. But there are much easier ways to do what you are trying to accomplish!To do what you want to do, you will either have to delimit your integer values in some way, and then parse the strings in the file, or use a BinaryWriter/BinaryReader instead.
Perhaps the easiest way to do this is to put one value per line like this:
If you want to minimize the file size, then I recommend writing each int with a
BinaryWriter
, and then reading the values with theBinaryReader.ReadInt32()
method. If you do that, then the file will be exactly4 * GameConstants.MapMaxTilesX * GameConstants.MapMaxTilesY
bytes long.Another fun way to do this would be to write each row of your map on its own line, and separate each column with a tab character
'\t'
. Then you could read the values back a line at a time and usestring.Split
to separate the values on each line. The advantage of this approach is that you can edit the file in a spreadsheet program or text editor.当从流中逐字节读取值时,Stream.Read() 返回当前字符的 ASCII 代码,因此您首先需要将其转换为常规 char,然后将其解析为 int。因此,不要这样做:
你需要这样做:
这应该可以解决问题。
When reading values from a stream byte by byte, the Stream.Read() returns the ASCII code of the current caracter so you first need to convert it to a regular char and then parse it as a int. So instead of doing:
You need to do:
And that should do the trick.