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

发布于 2024-08-05 09:53:54 字数 1298 浏览 7 评论 0原文

简而言之,我一直在尝试在 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 中实现这种面向行的读取器的最简单方法是什么? :s

Simply I have been trying to implement what BufferedStreamReader does in Java. I have a socket stream open and just want to read it in a line-oriented fashion - line by line.

I have the following server-code.

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());
            }
        }

And the following client-code:

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();
        }

The server reads only the very first line (login>user,pass) and then ReadLine returns null!

What's the easiest way of achieving this line-oriented reader as it is in Java's BufferedStreamReader? :s

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

顾冷 2024-08-12 09:53:54

典型的行读取器类似于:(

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;
        }
    }
}

注意我们已经将它移动到一个函数中并删除了“做某事”,用“yield return”替换它,这创建了一个迭代器(一个延迟迭代的、非-缓冲状态机)

然后我们可以简单地使用它:

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

现在我们的处理代码不需要担心如何读取行 - 只需给定一系列行, 请注意

using (Dispose()) 也适用于 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());
    }
}

A typical line-reader is something like:

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

(note the using to ensure we Dispose() it even if we get an error, and the loop)

If you want, you could abstract this (separation of concerns) with an iterator block:

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;
        }
    }
}

(note we've moved this into a function and removed the "do something", replacing it with "yield return", which creates an iterator (a lazily iterated, non-buffering state machine)

We would then consume this as simply as:

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

Now our processing code doesn't need to worry about how to read lines - simply given a sequence of lines, do something with them.

Note that the using (Dispose()) applies to TcpClient too; you should make a habit of checking for IDisposable; for example (still including your error-logging):

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());
    }
}
兰花执着 2024-08-12 09:53:54

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

The while in your server code is setup to only read one line per connection. You'll need another while within the try to read all of the lines being sent. I think once that stream is setup on the client side, it is going to send all of the data. Then on the server side, your stream is effectively only reading one line from that particular stream.

忘羡 2024-08-12 09:53:54
    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 编码

    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 is a socket.
for some rezone the TcpClient class doesn't work right on my pc any more,
but the Socket class works just fine.

UTF-8 is the stranded StreamReader / Writer Encoding

浅忆 2024-08-12 09:53:54

尝试了这个并得到了

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

Tried this and got

The type or namespace name 'Stream' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'StreamReader' could not be found (are you missing a using directive or an assembly reference?)
The type or namespace name 'StreamReader' could not be found (are you missing a using directive or an assembly reference?)
'System.Net.Sockets.Socket' does not contain a definition for 'GetStream'

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文