MSysGit管道编码
本文关键字:编码 管道 MSysGit | 更新日期: 2023-09-27 17:54:43
我试图将一个git进程的输出作为输入管道传输到另一个git命令。但我就是不能成功。Git版本1.9.5.msysgit.0
我想用代码做什么:
git show e46b22be3031ed53e80472002d332a2588f122c9 | git patch-id
Output:
c2a55fcbc40da401f84ae3b72c250e55f827001a e46b22be3031ed53e80472002d332a2588f122c9
我已经将输出管道传输到一个文件中,这样我就可以进行比较了:
git show e46b22be3031ed53e80472002d332a2588f122c9 > git.show.txt
从文件重定向输入会产生预期的结果:
git patch-id < commit.show.txt
Output:
c2a55fcbc40da401f84ae3b72c250e55f827001a e46b22be3031ed53e80472002d332a2588f122c9
为了帮助我解决这个问题,我写了一个代理应用程序:
- 从git show 读取管道输入
- 将管道输入写入文件,以便与git.show.txt 进行比较。
- 将管道输入写入输出,以便下一个应用程序可以将其管道化
现在的用法是:
git show e46b22be3031ed53e80472002d332a2588f122c9 | ConsolePipeConsumer.exe | git patch-id
Incorrect Output:
cf55b48fa7c9ed6f7214641c4d709667abfeb078 e46b22be3031ed53e80472002d332a2588f122c9
我写的临时文件是二进制的,等于git.show.txt,所以读取输入如预期的那样工作。
我就是想不出代理应用程序的标准输出的代码页。能想到的我都试过了。还是还有什么东西不见了?
代码如下:
using System;
using System.IO;
using System.Text;
namespace ConsolePipeConsumer
{
class Program
{
static void Main(string[] args)
{
try
{
var encoding = Encoding.Default;
Console.SetIn(new StreamReader(Console.OpenStandardInput(8192), encoding));
Console.Error.WriteLine("StdOut.Encoding={0}", Console.Out.Encoding);
// What encoding to use for output?
//Console.SetOut(new StreamWriter(Console.OpenStandardOutput(8192), encoding));
int c;
var sb = new StringBuilder();
while ((c = Console.Read()) >= 0)
{
sb.Append((char)c);
}
Console.Write(sb.ToString());
var tmp = Path.GetTempFileName();
File.WriteAllText(tmp, sb.ToString(), encoding);
Console.Error.WriteLine("Piped input written to: " + tmp);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
}
}
}
似乎错误是我没有冲洗控制台。在退出代理应用程序之前退出。
我还按照Edward Thompson的建议通过读写字节来改进代码。
下面是一个代理应用程序的工作实现:
- 接受管道输出,例如git
- 写关于输入 的调试信息
- 然后将完全相同的数据传输到输出。
代码如下:
<!-- language: c# -->
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
namespace ConsolePipeConsumer
{
class Program
{
static void Main(string[] args)
{
try
{
var pid = Process.GetCurrentProcess().Id;
var buffer = new byte[1024];
var tmp = new FileInfo(Path.GetTempFileName());
using (var reader = new BinaryReader(Console.OpenStandardInput(8192)))
using (var writer = new BinaryWriter(Console.OpenStandardOutput(8192)))
using (var tmpWriter = new BinaryWriter(tmp.Create()))
{
int c;
int len = 0;
while ((c = reader.Read(buffer, 0, buffer.Length)) > 0)
{
writer.Write(buffer, 0, c);
tmpWriter.Write(buffer, 0, c);
len += c;
}
Console.Error.WriteLine("[{0}] Input length: {1}", pid, len);
Console.Error.WriteLine("[{0}] Piped input written to: ", pid);
Console.Error.WriteLine("[{0}] {1} (File Size={2})", pid, tmp, tmp.Length);
writer.Flush();
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.ToString());
}
}
}
}