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

StreamReader ReadLine()返回空字符串,列表中未添加任何内容

您所指的具体问题是,因为您一次读取一个字符,当您看到]时,您会执行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得到满足,则在该字符之后读取不首先满足的下一个字符,如果条件