如何在Mono Apache MVC2应用程序中将标准输出管道传输到浏览器.下面的
本文关键字:传输 管道 浏览器 标准输出 Mono Apache MVC2 应用程序 | 更新日期: 2023-09-27 18:28:47
下面的
代码用于在Linux中的Apache Mono MVC2 Web应用程序中保存来自浏览器的PostgreSQL数据库备份。
在文件传输开始之前,备份需要很长时间才能完成。 pg_dump可以写入标准输出而不是文件。如何在不创建临时文件的情况下强制控制器将标准输出管道传输到浏览器?或者如何向用户显示一些进度指示器?
[Authorize]
public class BackupController : ControllerBase
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Backup()
{
var pinfo = new ProcessStartInfo();
var fn = "temp.backup";
pinfo.Arguments = " -f '"" + fn + "'" -Fc -h '"" + "myserver" + "'" -U '"" + "postgres" + " '"" + "mydb" + "'"";
pinfo.FileName = "/usr/lib/pgsql/pg_dump";
pinfo.UseShellExecute = false;
using (var process = new Process())
{
process.EnableRaisingEvents = true;
process.StartInfo = pinfo;
process.Start();
while (!process.HasExited)
Thread.Sleep(2000);
process.WaitForExit();
if (process.ExitCode!=0)
throw new Exception("error");
process.Close();
}
Response.ClearContent();
Response.WriteFile(fn);
Response.End();
System.IO.File.Delete(fn);
return null;
}
}
更新
我根据答案尝试了下面的代码。从浏览器保存的备份副本会导致pg_restore崩溃。如何使用二进制写入或其他东西来创建正确的备份?此外,浏览器仅在pg_dump完成后提示保存。如何实现管道,以便在pd_dump工作时通过互联网传输数据?
[Authorize]
public class BackupController : ControllerBase
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Backup()
{
Response.ClearContent();
Response.AddHeader("content-disposition", string.Format("attachment; filename='"backup.backup'"");
Response.ContentType = "application/backup";
using (var process = new Process())
{
process.StartInfo.Arguments = " -ib -Z6 -Fc -h '"server'"";
process.StartInfo.FileName = "/usr/lib/pgsql/pg_dump";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
Server.ScriptTimeout = 86400;
process.Start();
while (!process.HasExited)
{
var b = process.StandardOutput.ReadToEnd();
Response.Write(b);
Thread.Sleep(2000);
}
process.WaitForExit();
if (process.ExitCode != 0)
{
return new ContentResult()
{
Content = "Error " + process.ExitCode.ToString()
};
}
var b2 = process.StandardOutput.ReadToEnd();
Response.Write(b2);
process.Close();
Response.End();
return null;
}
}
您可以使用
RedirectStandardOutput将标准输出重定向到流,然后从Process.StandardOutput读取,这使您能够显示一些进度(结合AJAX左右,您可能很了解(。
也许将输出流写入临时缓冲区(文件或内存流(,而另一个线程使用 singnalR 通过管道传输到浏览器? 这里有一个很好的视频演示了 signalR:http://channel9.msdn.com/Shows/Web+Camps+TV/Damian-Edwards-and-David-Fowler-Demonstrate-SignalR
它将允许您在流内容更改时实时将数据发送到浏览器。 另外,你说有损坏,我只说这个因为它不止一次咬我,确保你使用相同的字符编码序列化和反序列化你的输出。