StreamReader ReadLine()返回空字符串,列表中未添加任何内容
本文关键字:列表 添加 任何内 字符串 ReadLine 返回 StreamReader | 更新日期: 2023-09-27 18:12:26
从文件读取列表时遇到一些问题。文件内容如下:
[ROOM101]
that way this way no way all the way
[END]
[ROOM102]
all the way that way this way no way
[END]
[ROOM103]
no way all the way that way this way
[END]
方法看起来是这样的:
public static List<Room> ReadRooms(string path)
{
List<Room> rooms = new List<Room>();
StreamReader reader = new StreamReader(path);
bool roomsLeft = true;
char currentChar;
string directions;
StringBuilder builder = new StringBuilder();
while (roomsLeft) {
currentChar = (char)reader.Read();
if (currentChar == '[') {
currentChar = (char)reader.Read();
while (currentChar != ']') {
builder.Append(currentChar);
currentChar = (char)reader.Read();
}
if (builder.ToString() != "END") {
directions = reader.ReadLine();
rooms.Add(new Room(builder.ToString(), directions));
}
}
if (reader.EndOfStream) {
roomsLeft = false;
}
}
reader.Close();
return rooms;
}
它读取第一行很好,但directions = ReadLine()
绝对不返回任何内容,也不会向列表中添加任何内容——它不应该跳到下一行并分配给directions
吗?。整个过程产生了一个StackOverflowException
。
您所指的具体问题是,因为您一次读取一个字符,当您看到]
时,您会执行ReadLine
,但这只会读取]
之后的换行符,而不是您想要的下一行。但是,即使你修复了代码中的其他问题(比如没有清除StringBuilder
(,最好只处理行,而不是一次读取一个字符。此外,您可以使用方便的File.ReadLine
方法,而不是使用需要清理的StreamReader
。
public static List<Room> ReadRooms(string path)
{
List<Room> rooms = new List<Room>();
bool inRoom = false;
StringBuilder directions = new StringBuilder();
string name = null;
foreach (var line in File.ReadLines(path))
{
if (inRoom)
{
if(line == "[END]")
{
rooms.Add(new Room(name, directions.ToString()));
inRoom = false;
directions.Clear();
}
else if (line.StartsWith("[") && line.EndsWith("]"))
{
// Found a start before the end, condiser throwing an
// exception, ignoring, or keep it as part of the directions.
}
else
{
directions.AppendLine(line);
}
}
else
{
if(line == "[END]")
{
// Found an end before a start either throw an exception or
// just ignore this.
}
else if (line.StartsWith("[") && line.EndsWith("]"))
{
inRoom = true;
name = line.Trim('[', ']');
}
else
{
// Consider throwing an exception here or just ignoring lines
// between [END] and the next room.
}
}
}
if (inRoom)
{
// Determine what to do if you had a room start, but no [END]
}
return rooms;
}
我已经包含了一些潜在的错误案例,您需要决定如何处理。
读取]
字符后,您认为读取该行已完成,并认为directions = reader.ReadLine();
将以这种方式获得,而不是以任何方式获得
但是,由于]
后面有"换行符",所以您还没有完成对该行的读取,并且您的读取器确实读取了该行并返回了一个空字符串。
我已经将您的方法重构为
public static List<Room> ReadRooms(string path)
{
List<Room> rooms = new List<Room>();
string roomName=String.Empty;
StringBuilder directionsBuilder= new StringBuilder();
using (StreamReader reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line != null && line.StartsWith("[END]"))
{
rooms.Add(new Room(roomName, directionsBuilder.ToString()));
directionsBuilder.Clear();
}
else if (line != null && line.StartsWith("["))
roomName = line.Substring(1, line.Length - 2);
else
directionsBuilder.AppendLine(line);
}
}
return rooms;
}
它应该处理多行方向以及房间名称,如ROOM102或APARTMENT201等。
如果While中的with得到满足,则在该字符之后读取不首先满足的下一个字符,如果条件