【发布时间】:2016-08-31 18:07:43
【问题描述】:
我正在使用SSH.NET 库使用inotifywait 命令在远程Linux 服务器上实现文件系统观察程序。本质上它是一个包装器:
ssh myhost "inotifywait -m -e close_write --format '%:e %f' /dropzone"
该命令将打印出来(到 STDOUT):
CLOSE_WRITE:CLOSE foo
CLOSE_WRITE:CLOSE bar
CLOSE_WRITE:CLOSE baz
这很简单,可以解析并转化为事件。无论如何,我的 c# 代码本质上是:
var privateKeyFile = new PrivateKeyFile(identity);
var client = new SshClient(hostname, username, privateKeyFile);
SshCommand command = null;
IAsyncResult result = null;
try
{
client.Connect();
command = client.CreateCommand("inotifywait -m -e close_write --format '%:e %f' " + dropZone);
result = command.BeginExecute();
Console.WriteLine("Watching for events");
var reader = new StreamReader(command.OutputStream);
string line = null;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
Console.WriteLine("Reached end of stream");
}
finally
{
if (client != null)
{
Console.WriteLine("Close the connection");
client.Dispose();
}
}
Console.WriteLine("Press enter to quit");
Console.ReadLine();
在写入单个文件后运行它会产生以下输出:
Watching for events
CLOSE_WRITE:CLOSE baz
Reached end of stream
Close the connection
Press enter to quit
Watching for events 立即出现并等待第一个文件被写入(阻塞等待,正如我对StreamReader 所期望的那样)。然而,下一个 ReadLine,而不是另一个阻塞等待,返回 null(表示流结束),即使命令仍在愉快地运行。我知道我可以这样改变循环:
while (!result.IsCompleted)
{
line = reader.ReadLine();
if (line != null)
{
Console.WriteLine(line);
}
}
结果:
Watching for events
CLOSE_WRITE:CLOSE baz
CLOSE_WRITE:CLOSE bar
CLOSE_WRITE:CLOSE foo
...
如所愿,但它摆脱了阻塞等待新输入,这意味着循环不断旋转(显然不希望......)
你能解释一下这种行为吗?对另一种方法有什么建议吗?
---- 更新----
该库看起来正在迁移到 github 并进行更新。我已提交this issue 以尝试解决此问题。
【问题讨论】:
-
如何摆脱阻塞等待?您使用相同的阻塞 reader.ReadLine。
-
@Evk,我不明白你在说什么......是的,我使用的是相同的
reader.ReadLine,但是,据我了解StreamReader调用ReadLine应该阻止如果当前没有要读取的数据,并且您还没有到达流的末尾。由于此命令永远不会到达流的末尾,因此每次调用都应该阻塞,直到出现新消息。至少这是期望的行为...... -
所以你验证了在一个 reader.ReadLine 返回 null 之后,下一个不会阻塞并立即再次返回 null?我的意思是您是否验证了“循环不断旋转”的假设?
-
@Evk,是的,我确实验证了这一点。 (事实上,这就是为什么我将
Console.WriteLine(line)包装在 if 语句中以防止打印所有空值)。 -
发生这种情况时 reader.EndOfStream 是否也返回 true?我看到你只检查 result.IsCompleted。
标签: c# streamreader ssh.net