아래 코드는 Linux의 Apache Mono MVC2 웹 응용 프로그램의 브라우저에서 PostgreSql 데이터베이스 백업을 저장하는 데 사용됩니다.Mono Apache MVC2 응용 프로그램에서 브라우저에 stdout을 파이프하는 방법
파일 전송이 시작되기 전에 백업이 완료되는 데 시간이 오래 걸립니다. pg_dump는 file 대신 표준 출력에 쓸 수 있습니다. 임시 파일을 만들지 않고 컨트롤러가 표준 출력을 브라우저로 파이프하도록하려면 어떻게해야합니까? 또는 진행률 표시기를 사용자에게 표시하는 방법은 무엇입니까?
[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;
}
}
감사합니다. 시도했지만 백업 복사본이 손상되어 파이프되지 않았습니다. 나는 질문을 업데이트했다. – Andrus
@Andrus : ReadToEnd()를 사용하고 있기 때문입니다. 다음과 같은 루프에서 프로세스의 출력을 읽는 것을 고려하십시오. 청크 읽기, 쓰기 대신 응답 (BinaryWrite 사용) 작성, flush 메소드 호출, 스트림 종료까지 모두 반복 –