【发布时间】:2019-09-23 11:39:39
【问题描述】:
我正在通过 Process 运行一个 exe 文件,它会生成二进制数据,我想将该数据保存到一个文件中。
在使用通常建议的方法(同步和异步)时,我遇到了几个障碍,希望您能帮助我。
我已经通过代码和提示符运行了命令,这是我的观察结果
1) 使用同步方法时,文件默认使用 UTF-8 编码(文件最终大于提示符 2)当将编码方法更改为 ASCII/默认时,编码似乎得到了正确处理,文件的大小似乎与提示符相似,不幸的是,旨在读取该文件的过程认为它“错误” 3) 使用 async 方法并使用 BinaryWriter 保存创建了一个看似准确的文件,但仍然无法通过输出读取。我相信我的错误可能是我如何附加“新行”
下面是我的异步方法代码。虽然同步一个在开始/停止之间只有“Output.ReadToEnd()”。
代码:
private void createOCTree()
{
//Create process
var cmd = @"oconv.exe"; //OUTPUT IS C++ binary
var arguments = @" C:\RadianceGeometry.rad";
var outputFile = @"C:\test.oct";
var workingDir = m_FileData.TemporaryFilesFolder;
ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
cmdStartInfo.RedirectStandardInput = false;
cmdStartInfo.RedirectStandardError = false;
cmdStartInfo.RedirectStandardOutput = true;
cmdStartInfo.UseShellExecute = false;
cmdStartInfo.CreateNoWindow = true;
cmdStartInfo.FileName = cmd; ////file name
cmdStartInfo.Arguments = arguments; ////arguments
cmdStartInfo.WorkingDirectory = @"C:\"; ////working dir
using (StreamWriter writer = new StreamWriter("C:\\testStream.oct"))
{
}
var process = new Process();
process.StartInfo = cmdStartInfo;
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
}
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
try
{
byte[] bytes = Encoding.Default.GetBytes(outLine.Data);
byte[] newLine = Encoding.Default.GetBytes("\n");
AppendData("C:\\testStream.oct", bytes);
AppendData("C:\\testStream.oct", newLine); ////otherwise all is in one line
}
catch { } ////possibly last line is not properly handled
}
private static void AppendData(string filename, byte[] bits)
{
using (var fileStream = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None))
using (var bw = new BinaryWriter(fileStream))
{
bw.Write(bits);
}
}
我的怀疑是我的“Try/Catch”遗漏了一些东西,或者换行符应该以不同的方式解析。 将所有路径设置为 c:\ 只是为了使其更易于阅读(而不是使用变量或实际路径)。
编辑:添加;我注意到在将提示输出与代码中的输出进行比较时,它们是相同的,除了某些行“输出”的第一个字符是“?”而不是工作文件中的随机“字形”。
编辑:添加了比较屏幕截图。 代码对比:
没有换行符:https://ibb.co/Lvcr9pH
【问题讨论】:
-
二进制数据中没有行。检查源和目标的文件大小以查看它们是否相同。使用 Beyond Compare 将有助于确定差异发生在哪里。从不,从不,从不对二进制数据使用编码,它会破坏数据。编码会改变和删除字符。甚至 UTF8 也会改变字符 0x80。只需使用 BinaryWriter 节省蒸汽。
-
感谢您的回复。我第一次尝试没有换行,但使用NL时输出似乎更符合提示结果。使用新行ibb.co/HpztQ0Q 不使用新行ibb.co/Lvcr9pH 代码不同之处在于某些地方的位被替换为“?”,我不知道该怎么办。
-
您不能在二进制文件中使用换行符。使用 List
然后 AddRange 追加数据。 -
用列表试过了,但没有太大区别; ibb.co/Pmh1GG7(注意与“正常”文件相比多出 156 个字节)
-
对于二进制,任何差异(即使是一个字符)都是一个问题。检查差异是接收数据还是仅写入。
标签: c# asynchronous process binary output