2009-09-20 98 views
11

简单地说,我一直在试图实现BufferedStreamReader在Java中的作用。我有一个套接字流打开,只是想以面向行的方式逐行读取它。C# - StreamReader.ReadLine无法正常工作!

我有以下服务器代码。

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返回空!

在Java的BufferedStreamReader中,实现这种面向行的阅读器的最简单方法是什么? :s

+1

请,处置您的物体在这里(的的StreamReader和StreamWriter)。否则,您可能会遇到意外问题。简单地在它们周围放置一个使用块(如使用(StreamWriter writer = ...){}),并且你会好的 – configurator 2009-09-20 04:15:42

+0

不是它与问题相关 - 只是一个建议。 – configurator 2009-09-20 04:16:12

+0

很棒; )感谢 – Aleyna 2009-09-20 04:31:20

回答

12

一个典型的线阅读器是一样的东西:

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

(注意,我们已经转移到这个功能,并去掉了“做什么”,replaci与“收益率的回报”,这将创建一个迭代器(一个懒洋洋地迭代,非缓冲状态机)

然后,我们将消耗该纳克它只是为:

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

当我使用StreamReader从套接字读取数据时,发现客户端程序处于冻结状态,在ReadLine()方法中占用无限时间,最后无法读取。 – 2015-09-17 04:36:43

+0

@MasudRahman通常意味着:服务器没有发送一个完整的行(即你要求它等待服务器没有理由发送给你的东西),或者服务器忘记刷新输出缓冲区。您*可以*添加读取超时,但最终不能使服务器发送数据。你当然可以做自己的阅读和缓冲,但这只是改变了问题的本质 - 然后可以确定在一段时间后一条完整的线路未被发送。 – 2015-09-17 09:21:53

5

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

+0

改变我的服务器和客户端的代码如下 服务器后: 使用(StreamReader的读者=新的StreamReader(Socket.GetStream(),Encoding.UTF8)){ 而 (continueProcess) .... 客户端: ... Thread.Sleep(10000); writer.WriteLine(“print> test,one,two”); 我插入Thread.Sleep(10000)到我的客户端代码和服务器开始抛出异常。客户端套接字将被打开,直到客户端退出,并且客户端将在其整个生命周期中发送数据,看起来像这样的代码会抛出错误。你不这么认为吗? – Aleyna 2009-09-20 04:49:24

+0

没有看到新代码或新异常是什么,我不确定问题可能是什么。 – LJM 2009-09-20 04:58:56

0

尝试这样做,得到了

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

+1

请参考http://msdn.microsoft.com/en-us/library/system.io.stream.aspx – Aleyna 2010-11-06 04:10:05

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是一个套接字。 对于某些rezone,TcpClient类在我的电脑上无法正常工作, 但Socket类工作正常。

UTF-8是搁浅的StreamReader /写入器编码