C# - StreamReader.ReadLine无法正常工作!

时间:2009-09-20 03:53:19

标签: c# .net readline streamreader bufferedstream

我一直在尝试实现Java中BufferedStreamReader的功能。我打开了一个套接字流,只想逐行地逐行阅读它。

我有以下服务器代码。

while (continueProcess)
        {
            try
            {
                StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8);
                string command = reader.ReadLine();
                if (command == null)
                    break;

                OnClientExecute(command);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

以下客户端代码:

TcpClient tcpClient = new TcpClient();
        try
        {
            tcpClient.Connect("localhost", serverPort);
            StreamWriter writer = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
            writer.AutoFlush = true;
            writer.WriteLine("login>user,pass");
            writer.WriteLine("print>param1,param2,param3");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
        finally
        {
            tcpClient.Close();
        }

服务器只读取第一行(login>user,pass),然后ReadLine返回null!

实现这种面向行的读者的最简单方法是什么,就像在Java BufferedStreamReader中一样? :■

4 个答案:

答案 0 :(得分:13)

典型的线路阅读器类似于:

using(StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8)) {
    string line;
    while((line = reader.ReadLine()) != null) {
        // do something with line
    }
}

(请注意using以确保我们Dispose()即使我们收到错误,并且循环播放)

如果需要,可以使用迭代器块抽象(关注点分离):

static IEnumerable<string> ReadLines(Stream source, Encoding encoding) {
    using(StreamReader reader = new StreamReader(source, encoding)) {
        string line;
        while((line = reader.ReadLine()) != null) {
            yield return line;
        }
    }
}

(注意我们已将其移动到一个函数中并删除了“do something”,将其替换为“yield return”,这将创建一个迭代器(一个延迟迭代的非缓冲状态机)

然后我们将其简单地用作:

foreach(string line in ReadLines(Socket.GetStream(), Encoding.UTF8)) {
    // do something with line
}

现在我们的处理代码不需要担心 如何读取行 - 只需给出一系列行,用它们做点什么。

请注意,usingDispose())也适用于TcpClient;你应养成检查IDisposable的习惯;例如(仍包括错误记录):

using(TcpClient tcpClient = new TcpClient()) {
    try {
       tcpClient.Connect("localhost", serverPort);
       StreamWriter writer = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
       writer.AutoFlush = true;
       writer.WriteLine("login>user,pass");
       writer.WriteLine("print>param1,param2,param3");
    } catch (Exception ex) {
        Console.Error.WriteLine(ex.ToString());
    }
}

答案 1 :(得分:5)

服务器代码中的while设置为每个连接只读取一行。在尝试读取所有发送的行时,您将需要另一个。我想一旦在客户端设置了该流,它将发送所有数据。然后在服务器端,您的流实际上只从该特定流中读取一行。

答案 2 :(得分:0)

试过这个并得到了

找不到类型或命名空间名称'Stream'(您是否缺少using指令或程序集引用?) 找不到类型或命名空间名称'StreamReader'(您是否缺少using指令或程序集引用?) 找不到类型或命名空间名称'StreamReader'(您是否缺少using指令或程序集引用?) 'System.Net.Sockets.Socket'不包含'GetStream'的定义

答案 3 :(得分:0)

    public string READS()
    {
        byte[] buf = new byte[CLI.Available];//set buffer
        CLI.Receive(buf);//read bytes from stream
        string line = UTF8Encoding.UTF8.GetString(buf);//get string from bytes
        return line;//return string from bytes
    }
    public void WRITES(string text)
    {
        byte[] buf = UTF8Encoding.UTF8.GetBytes(text);//get bytes of text
        CLI.Send(buf);//send bytes
    }

CLI是一个套接字。 对于某些重新区域,TcpClient类不再适用于我的电脑, 但是Socket类工作正常。

UTF-8是搁浅的StreamReader / Writer编码

相关问题