使用 dotnet core 的 NamedPipeClientStream 或 NamedPipeServerStream 类创建命名管道时,关联的“管道”(看起来实际上是一个套接字)会自动在文件名前面添加“CoreFxPipe_”。
有没有一种非黑客的方法来防止这种行为?我只是希望文件名与我提供给构造函数的名称完全相同。
在 dotnet core documentation 中,它描述了以下构造函数:
NamedPipeServerStream(字符串)
使用指定的管道名称初始化 NamedPipeServerStream 类的新实例。
但是,由于上述原因,此描述充其量似乎具有误导性。
解决方案:
使用绝对路径作为管道名称
详情:
查看NamedPipeClientStream的源代码,第93行显示管道名称是通过调用GetPipePath(PipeStream类的方法)“标准化”的。查看PipeStream的源代码,GetPipePath是在第35行实现的。
该方法似乎检查“IsPathRooted”(大概是;管道名称是绝对路径)。如果是,那么它将让您“完全控制”定义套接字的路径。否则,它将把套接字放在 /tmp/ 中,并在文件名中添加前缀 CoreFxPipe_。
如果您使用的操作系统是 unix/ubuntu 并且您想使用命名管道 (mkfifo) 而不是流,那么这里有一些通过 System.IO.FileStream 执行此操作的 C# 代码
using System;
using System.IO;
using System.Threading.Tasks;
// Use unix mkfifo named pipe rather than stream
public class NamedPiper2
{
public static void Create(string pipeName){
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "mkfifo";
startInfo.Arguments = pipeName;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
Console.WriteLine("Created Named Pipe: " + pipeName);
}
public static void Close(string pipeName){
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "rm";
startInfo.Arguments = pipeName;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
Console.WriteLine("Closed Named Pipe: " + pipeName);
}
public static void Read(string pipeName)
{
// Open the named pipe for reading
using (FileStream pipeStream = new FileStream(pipeName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (StreamReader reader = new StreamReader(pipeStream))
{
bool trucking = true;
while(trucking){
var message = reader.ReadLine();
if(message == null){
Task.Delay(1000).Wait();
}else{
Console.WriteLine("Read Received message: " + message);
if(message.Trim() == "bye") trucking = false;
}
}
}
}
}
}