0

以下のコードは、LinuxのApache MonoMVC2Webアプリケーションのブラウザーから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;
        }
    }
4

2 に答える 2

0

RedirectStandardOutputを使用して標準出力をストリームにリダイレクトし、 Process.StandardOutputから読み取ることができます。これにより、進行状況を表示できます (AJAX などと組み合わせて、おそらくよく知っているでしょう)。

于 2012-03-24T09:46:51.187 に答える
0

別のスレッドが singnalR を使用してブラウザーにパイプしている間に、出力ストリームを一時バッファー (ファイルまたはメモリ ストリーム) に書き込む可能性がありますか? signalR のデモ動画はこちら: http://channel9.msdn.com/Shows/Web+Camps+TV/Damian-Edwards-and-David-Fowler-Demonstrate-SignalR

ストリームの内容が変化するのに合わせて、リアルタイムでブラウザにデータを送信できます。また、あなたは破損があったと言いますが、これは私が何度も噛まれた原因であるとだけ言っています。同じ文字エンコーディングで出力をシリアル化および逆シリアル化するようにしてください。

于 2012-03-25T20:16:25.250 に答える