我正在尝试做一些看起来相对简单的事情:从C#调用jpegoptim。
我可以让它很好地写入磁盘,但是到目前为止,让它接受一个流并发出一个流是我所不能理解的--我总是以0长度的输出结束,或者是不祥的“管道已经结束”。
我尝试过一种方法:
var processInfo = new ProcessInfo(
jpegOptimPath,
"-m" + quality + " -T1 -o -p --strip-all --all-normal"
);
processInfo.CreateNoWindow = true;
processInfo.WindowStyle = ProcessWindowStyle.Hidden;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardInput = true;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;
using(var process = Process.Start(processInfo))
{
await Task.WhenAll(
inputStream.CopyToAsync(process.StandardInput.BaseStream),
process.StandardOutput.BaseStream.CopyToAsync(outputStream)
);
while (!process.HasExited)
{
await Task.Delay(100);
}
// Do stuff with outputStream here - always length 0 or exception
}我也尝试过这个解决方案:
http://alabaxblog.info/2013/06/redirectstandardoutput-beginoutputreadline-pattern-broken/
using (var process = new Process())
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.FileName = fileName;
process.StartInfo.Arguments = arguments;
process.Start();
//Thread.Sleep(100);
using (Task processWaiter = Task.Factory.StartNew(() => process.WaitForExit()))
using (Task<string> outputReader = Task.Factory.StartNew(() => process.StandardOutput.ReadToEnd()))
using (Task<string> errorReader = Task.Factory.StartNew(() => process.StandardError.ReadToEnd()))
{
Task.WaitAll(processWaiter, outputReader, errorReader);
standardOutput = outputReader.Result;
standardError = errorReader.Result;
}
}同样的问题。输出长度为0。如果我让jpegoptim在没有输出重定向的情况下运行,我会得到我所期望的-一个优化的文件-但当我以这种方式运行它时就不是这样了。
一定要有正确的方法才能做到这一点?
更新:发现了一个线索-我不觉得害羞吗- jpegoptim从来没有支持管道到stdin,直到2014年的一个实验性构建,今年修复。我的版本来自一个更老的库,日期是2013年。https://github.com/tjko/jpegoptim/issues/6
发布于 2015-11-06 00:39:34
部分解决方案-参见下面的死锁问题。我在最初的尝试中遇到了多个问题:
jpegoptim你需要一个构建的来读写管道,而不是只读写文件。正如前面提到的builds prior to mid-2014 can't do it。jpegoptim github "releases“是无用的源代码压缩,而不是构建的发行版,所以您需要在其他地方寻找实际的built releases.
--stdin和--stdout,并根据您将如何响应它,避免可能导致它什么都不写的参数,比如-T1 (当优化只有1%或更少时,太多的路都没有了。没有任何迹象表明原因。
var processInfo = new ProcessInfo(
jpegOptimPath,
"-m" + quality + " --strip-all --all-normal --stdin --stdout",
);
processInfo.CreateNoWindow = true;
processInfo.WindowStyle = ProcessWindowStyle.Hidden;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardInput = true;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;
using(var process = new Process())
{
process.StartInfo = processInfo;
process.Start();
int chunkSize = 4096; // Process has a limited 4096 byte buffer
var buffer = new byte[chunkSize];
int bufferLen = 0;
var inputStream = process.StandardInput.BaseStream;
var outputStream = process.StandardOutput.BaseStream;
do
{
bufferLen = await input.ReadAsync(buffer, 0, chunkSize);
await inputStream.WriteAsync(buffer, 0, bufferLen);
inputStream.Flush();
}
while (bufferLen == chunkSize);
do
{
bufferLen = await outputStream.ReadAsync(buffer, 0, chunkSize);
if (bufferLen > 0)
await output.WriteAsync(buffer, 0, bufferLen);
}
while (bufferLen > 0);
while(!process.HasExited)
{
await Task.Delay(100);
}
output.Flush();这里有一些需要改进的地方。欢迎改进。
最大的问题是:在一些图片中,这个死锁发生在
https://stackoverflow.com/questions/33535933
复制相似问题