C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.19072 の関連記事表示

<< 0 | 1 >>
■19072  Processの標準出力をリアルタイム取得
□投稿者/ 鶏唐揚 -(2008/05/20(Tue) 09:59:01)

    分類:[VB.NET/VB2005] 

    [OS]WinXP
    [VB]2003/2005

    お世話になっております。
    今回は表題の通り、ProcessのStandardOutputを逐次読み取りたいというものです

    わかりやすいとこで言うとPINGコマンド等、処理の間にもプロンプトに
    順次表示されるものを、呼び出し元で奪ってしまおうと思ったのですが
    当初書いた以下のコードでは当然ながら最終的な出力結果がまとめて返ってきます

    Dim proc As Process

    proc = New Process

    With proc.StartInfo
    .FileName = "PING"
    .Argument = "xxx.xxx.xx.xx" 'IPは伏せます
    .RedirectStandardOutput = True
    .WindowStyle = ProcessWindowStyle.Hidden
    .CreateNoWindow = True
    .UseShellExecute = False
    End With

    proc.Start()
    Debug.WriteLine(proc.StandardOutput.ReadToEnd())
    proc.WaitForExit(10000)

    proc.Close()
    proc.Dispose()
    proc = Nothing


    タイマーでReadToEndとも考えたのですが良く考えればStartで固まるので
    意味ありませんでした。
    マルチスレッド使わずに標準出力のリアルタイム取得を実現できる方法があれば
    ご教示願いたいと思います(マルチスレッド使って実現できるかどうかも未確認ですが)
親記事 /過去ログ37より / 関連記事表示
削除チェック/

■19073  Re[1]: Processの標準出力をリアルタイム取得
□投稿者/ れい -(2008/05/20(Tue) 10:11:29)
    No19072 (鶏唐揚 さん) に返信
    > タイマーでReadToEndとも考えたのですが良く考えればStartで固まるので
    > 意味ありませんでした。
    > マルチスレッド使わずに標準出力のリアルタイム取得を実現できる方法があれば
    > ご教示願いたいと思います(マルチスレッド使って実現できるかどうかも未確認ですが)

    ?
    普通に非同期よみこみなり
    長さを指定して読み込んだりすればいいだけではないでしょうか?

    Startで固まる、というのも理解不可能です。
    少し時間はかかりますが、すぐに戻ってくるような。

    何か違うことをいってるのでしょうか?
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19081  Re[2]: Processの標準出力をリアルタイム取得
□投稿者/ ネタ好き -(2008/05/20(Tue) 10:35:40)
    マルチスレッドで、共有する標準入力(コンソール)に出力される結果を、
    違う処理結果を混ぜないで得る方法ですよね?
    仮にそうだとして話を進めます。
    標準入力をコンソールに絞って言うと、マルチスレッドで結果を受け取り、
    受け取った直後にConsole.Clearで処理結果で埋まったコンソールを消してしまえばいいと思います。
    勿論、同期がらみのややこしい事は覚悟せねばなりませんが、
    こうする事により結果を混ぜないで出力結果を得られます。
    忙しいので検証しておりませんが是非お試しください。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19077  Re[2]: Processの標準出力をリアルタイム取得
□投稿者/ 鶏唐揚 -(2008/05/20(Tue) 10:30:56)
    No19073 (れい さん) に返信
    > ?
    > 普通に非同期よみこみなり
    > 長さを指定して読み込んだりすればいいだけではないでしょうか?
    >
    > Startで固まる、というのも理解不可能です。
    > 少し時間はかかりますが、すぐに戻ってくるような。
    >
    > 何か違うことをいってるのでしょうか?
    違うことを言ってるのかどうか判断しかねますが、
    もう少し具体的に書いてみます。

    Startで固まるというのは、PINGコマンドが完了するまでメインスレッドが待機して
    しまうということです。WaitForExitを外しても同様でした。

    コマンドプロンプトで単純に
    PING xxx.xxx.xx.xx
    と打つと、(PINGが通る場合は)通常は約1秒ごとにReply from...と
    4回表示されると思いますが、これをそのままのタイミングで
    標準出力を奪って表示したいということです。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19076  Re[1]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン -(2008/05/20(Tue) 10:29:03)
    No19072 (鶏唐揚 さん) に返信
    
    マルチスレッドでなく、という要件を満たすかどうかわかりませんが
    (非同期読み取りは内部的にマルチスレッドなので)、こんなコードでできました。
    構文的には C# 3.0、フレームワーク的にも .NET Framework 2.0 のを使っちゃってますけど。
    
    using (Process p = new Process())
    {
        p.StartInfo.FileName = "ping.exe";
        p.StartInfo.Arguments = "127.0.0.1";
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.UseShellExecute = false;
        p.OutputDataReceived += (sender, e) =>
        {
            if( ! string.IsNullOrEmpty(e.Data) )
            {
                Console.WriteLine(e.Data);
            }
        };
    
        p.Start();
        p.BeginOutputReadLine();
        p.WaitForExit();
    }
    
    Console.WriteLine();
    Console.WriteLine("Complete");
    
    が、DataReceivedEventArgs.Data には時折空文字列が来るようで、
    string.IsNullOrEmpty を外すと、数行の空行が出てしまいますが、
    排除すると、コマンドプロンプトから叩いた時の出るべき空行も排除してしまうので、
    そのままの出力を再現することはできませんでした。
    
    他にも方法はあるかと思います。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19080  Re[2]: Processの標準出力をリアルタイム取得
□投稿者/ 鶏唐揚 -(2008/05/20(Tue) 10:35:07)
    2008/05/20(Tue) 10:37:40 編集(投稿者)

    No19076 (シャノン さん) に返信
    > マルチスレッドでなく、という要件を満たすかどうかわかりませんが
    自分でマルチスレッド作って自分で制御して…というのをやりたくないというだけなので
    内部的にマルチスレッドになってるだけというのなら大丈夫です

    > (非同期読み取りは内部的にマルチスレッドなので)、こんなコードでできました。
    > 構文的には C# 3.0、フレームワーク的にも .NET Framework 2.0 のを使っちゃってますけど。
    >略
    > が、DataReceivedEventArgs.Data には時折空文字列が来るようで、
    > string.IsNullOrEmpty を外すと、数行の空行が出てしまいますが、
    > 排除すると、コマンドプロンプトから叩いた時の出るべき空行も排除してしまうので、
    > そのままの出力を再現することはできませんでした。
    >
    > 他にも方法はあるかと思います。
    ありがとうございます。上記コードを解析してVBにしてみます。
    空白行の問題はその後に考えてみます
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19078  Re[2]: Processの標準出力をリアルタイム取得
□投稿者/ れい -(2008/05/20(Tue) 10:32:26)
    2008/05/20(Tue) 10:36:01 編集(投稿者)

    No19076 (シャノン さん) に返信
    > (非同期読み取りは内部的にマルチスレッドなので)、こんなコードでできました。

    どこまで考えるかによりますが、
    ユーザーモードの範囲内なら非同期読み取りはマルチスレッドでないものもありますよ。
    特にストリームは。

    > 他にも方法はあるかと思います。

    じゃあWindows.Formsで。
    ただ、鶏唐揚さんが何をしたいのかいまいちよくわからないのですよね。
    こんな簡単なのでいいのかしら?


    Dim proc As Process
    Dim ar As IAsyncResult
    Dim dlg As ReadLine
    Delegate Function ReadLine() As String

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    If proc IsNot Nothing Then Exit Sub
    proc = New Process

    With proc.StartInfo
    .FileName = "PING"
    .Arguments = "192.168.68.1" '私のプライベートアドレスはこれ。
    .RedirectStandardOutput = True
    .WindowStyle = ProcessWindowStyle.Hidden
    .CreateNoWindow = True
    .UseShellExecute = False
    End With

    proc.Start()
    dlg = New ReadLine(AddressOf proc.StandardOutput.ReadLine)
    ar = dlg.BeginInvoke(Nothing, Nothing)
    Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    If ar.IsCompleted Then
    Dim str As String
    str = dlg.EndInvoke(ar)
    If str Is Nothing Then
    Timer1.Stop()
    proc = Nothing
    Else
    Me.TextBox1.Text &= str & ControlChars.NewLine
    ar = dlg.BeginInvoke(Nothing, Nothing)
    End If
    End If
    End Sub

    追記。

    > Startで固まるというのは、PINGコマンドが完了するまでメインスレッドが待機して
    > しまうということです。WaitForExitを外しても同様でした。

    StartではなくReadToEndで固まってるのではないですか?

    > コマンドプロンプトで単純に
    > PING xxx.xxx.xx.xx
    > と打つと、(PINGが通る場合は)通常は約1秒ごとにReply from...と
    > 4回表示されると思いますが、これをそのままのタイミングで
    > 標準出力を奪って表示したいということです。

    とすると、ストリームの扱いに慣れていないのでしょう。
    No18620 の投稿とかにちょっと書いたので参考に。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19085  Re[3]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン -(2008/05/20(Tue) 10:53:22)
    No19078 (れい さん) に返信

    > ■No19076 (シャノン さん) に返信
    >>(非同期読み取りは内部的にマルチスレッドなので)、こんなコードでできました。
    >
    > どこまで考えるかによりますが、
    > ユーザーモードの範囲内なら非同期読み取りはマルチスレッドでないものもありますよ。
    > 特にストリームは。

    んー。
    そう来るのは予想できていましたが、厳密に突き詰めても得るものはないですし。
    「マルチスレッドかもしれないので」くらいにしておいてください。

    >>他にも方法はあるかと思います。
    >
    > じゃあWindows.Formsで。

    「コンソールプロセスが終了するまで待機」というのをしなくていいのが楽ですね。
    個人的には、そこをどうするかが課題のひとつだと思っていますが。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19083  Re[3]: Processの標準出力をリアルタイム取得
□投稿者/ 鶏唐揚 -(2008/05/20(Tue) 10:49:55)
    >ただ、鶏唐揚さんが何をしたいのかいまいちよくわからないのですよね
    説明下手ですみません^^;

    んーーと…LameっていうMP3エンコーダは、プロンプトに進捗が表示されますよね。
    ProcessでLameを蹴って、その進捗表示をVB側で受け取ってリアルタイムで
    表示させておきたいなーというようなものです。
    が、私の方法ではStart(と当初はそう思っていたが実際はれいさんのご指摘どおりReadToEndでした)で
    待機してしまうため、どうすればええんかいなというわけです。

    非同期ができるということを知らなかったためちぐはぐな質問になってたようです。

    >とすると、ストリームの扱いに慣れていないのでしょう
    おっしゃるとおりです。正直ストリームというものに触ったのは.NETからなので
    ファイル入出力くらいにしか使ったことがありません…

    れいさんのコードも参考にさせていただきます

    Toネタ好きさん
    >マルチスレッドで、共有する標準入力(コンソール)に出力される結果を、
    >違う処理結果を混ぜないで得る方法ですよね?
    VB側はマルチスレッドしてないです。ProcessでPINGなりLameなりの
    コンソールアプリをキックし、その標準出力を出力された端から奪って表示したいけど
    今の方法じゃキック対象が終了してからそれまでの出力がまとめて返ってくるので困っていた
    ということです。言葉足らずで申し訳ございませんorz
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19096  Re[2]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン -(2008/05/20(Tue) 11:40:56)
    No19076 (シャノン さん) に返信
    > が、DataReceivedEventArgs.Data には時折空文字列が来るようで、
    > string.IsNullOrEmpty を外すと、数行の空行が出てしまいますが、
    > 排除すると、コマンドプロンプトから叩いた時の出るべき空行も排除してしまうので、
    > そのままの出力を再現することはできませんでした。

    これバグくさいなー。
    Framework のソースを追ってみたけど、BeginOutputReadLine の内部では、やっぱり StandardOutput.BaseStream.BeginRead を使って出力を読み取っている。
    それを文字列に整形する際に、バッファの中から \r と \n を探して、そこまでを1行として返すような処理をしている(AsyncStreamReader.GetLinesFromStringBuilder)。
    が、ステップ実行してみると、改行文字が \r\r\n と続く場合があり、このときは空行が2行連続してしまう。
    C でコンソールアプリを組んだとき、改行文字に \n ではなく \r\n を使ったプログラムを、コマンドプロンプトからテキストファイルにリダイレクトするとこういう現象が起こる。
    リダイレクトする際に \n を \r\n に置き換えて出力してくれるらしい。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19103  Re[3]: Processの標準出力をリアルタイム取得
□投稿者/ れい -(2008/05/20(Tue) 12:05:17)
    No19096 (シャノン さん) に返信
    > これバグくさいなー。

    pingの、ですね。

    No19095 (シャノン さん) に返信
    >>string output = Console.OutputEncoding.GetString(aa.buffer, 0, count);
    >>
    >>ここはダメですねぇ。
    >>GetDecoderしてDecoder取っておかないと、文字が化けちゃいます。
    >
    > え、そうなの?

    OutputEncodingがUTF-16なときに
    3バイトの読み込みで返ってきたりしたら切れちゃいますよ。
    必ず偶数まで読む、なんて保証はないですから。

    > それでもいいのか。
    > StreamReader を使うというのは良くわからんが。

    StreamReaderに折角「改行まで読む」というメソッドがあるのに使わないのはもったいないというだけです。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19106  Re[4]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン -(2008/05/20(Tue) 12:23:20)
    No19103 (れい さん) に返信
    > ■No19096 (シャノン さん) に返信
    >>これバグくさいなー。
    > 
    > pingの、ですね。
    
    そうなのかな?
    コンソールアプリは出力時に \r\n ではなく \n を使うべし、というガイドラインはどこかにあったっけ?
    例えばここ
    http://www.atmarkit.co.jp/fdotnet/dotnettips/657redirectstdout/redirectstdout.html
    では、出力を受ける側で \r\r\n に対応してるけど。
    
    > >>GetDecoderしてDecoder取っておかないと、文字が化けちゃいます。
    >>
    >>え、そうなの?
    > 
    > OutputEncodingがUTF-16なときに
    > 3バイトの読み込みで返ってきたりしたら切れちゃいますよ。
    > 必ず偶数まで読む、なんて保証はないですから。
    
    なるほど。勉強勉強。
    
    >>StreamReader を使うというのは良くわからんが。
    > StreamReaderに折角「改行まで読む」というメソッドがあるのに使わないのはもったいないというだけです。
    
    あー、ReadLine を非同期で呼べと。
    非同期デリゲートは使おうと思わなかったなぁ。
    
    というわけでれいさんのをパクった非同期デリゲート版。
    
    private delegate string ReadLine();
    private static void Ping3()
    {
        using (Process p = new Process())
        {
            p.StartInfo.FileName = "ping.exe";
            p.StartInfo.Arguments = "127.0.0.1";
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
    
            p.Start();
    
            for(;;)
            {
                ReadLine ln = p.StandardOutput.ReadLine;
                IAsyncResult ar = ln.BeginInvoke(null, null);
                ar.AsyncWaitHandle.WaitOne();
                string line = ln.EndInvoke(ar);
                if (line == null)
                {
                    break;
                }
    
                Console.WriteLine(line);
            }
        }
    
        Console.WriteLine();
        Console.WriteLine("Complete");
    }
    
    やっぱり改行が \r\r\n になるおまけつき。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19116  Re[5]: Processの標準出力をリアルタイム取得
□投稿者/ れい -(2008/05/20(Tue) 13:15:41)
    No19106 (シャノン さん) に返信
    > ■No19103 (れい さん) に返信
    >>■No19096 (シャノン さん) に返信
    > >>これバグくさいなー。
    >>
    >>pingの、ですね。
    >
    > そうなのかな?
    > コンソールアプリは出力時に \r\n ではなく \n を使うべし、というガイドラインはどこかにあったっけ?

    実際のpingのソースは知りませんが、
    pingの標準出力をパイプ経由で開いて読むと
    \r\r\nが返ってくるわけです。

    おそらく、標準出力がテキストモードであることを忘れて\r\nを出力しちゃってる、と見るのが普通でしょう。
    そうでなかったとしても、pingが\r\r\nを出しちゃってるのはほぼ確実で、
    やっぱりpingのバグです。

    パイプがバグもちで入力元がpingの時のみ\r\nを\r\r\nに変えてしまう、
    なんて確率はほぼ0と見ていいでしょう。

    pingが意図的に\rを出している、つまり仕様である可能性ももちろんありますが。
    その場合理由が見えません。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19173  Re[4]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン -(2008/05/20(Tue) 18:18:56)
    2008/05/20(Tue) 18:19:31 編集(投稿者)

    No19103 (れい さん) に返信
    > ■No19096 (シャノン さん) に返信
    >>これバグくさいなー。
    >
    > pingの、ですね。

    ping にバグがあるとして、その出力を扱うこっち側のアプリはどうしますか?
    ping は単一の改行のつもりで \r\n を書き出したところ、標準出力がテキストモードだったために \r\r\n になってしまうわけですが、Process.OutputDataReceived も Process.StandardOutput.ReadLine も、\r だけを有効な改行とみなすために、\r\r\n は2つの改行と認識されてしまうわけです。
    これを、「そんなのは ping のバグだから俺の責任じゃない! 知らん!」と言うか、\r\r\n は単一の改行と認識するようにプログラムを組むか。
    後者の場合、Process.StandardOutput.BaseStream からバイトデータとして読み取れば \r\r\n を受け取れるので処理できますが、Process.OutputDataReceived や Process.StandardOutput.ReadLine ではダメなんですよね(意図した空行かバグによる空行か判別できないため)。

    もちろん、ことは ping に限ったことではなく、行末が \r\r\n になってしまうコンソールアプリは少なくないことは想定できます。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19187  Re[5]: Processの標準出力をリアルタイム取得
□投稿者/ れい -(2008/05/20(Tue) 21:51:31)
    No19173 (シャノン さん) に返信
    > ping にバグがあるとして、その出力を扱うこっち側のアプリはどうしますか?

    基本的に他のバグへの対処と同じでいいかと。

    「入力には寛容に」ですから、
    1 そんなところを気にしなくていいようなプログラムにする
    というのが最初かな?

    で、だめなら
    2 個別に対応する

    でも、シャノンさんの言うように対象が少なくないでしょうから、
    仕方が無いときのみ
    3 全体的に対処できるように組む
    かな。

    でも、この\n->\r\nは不可逆ですから
    本来意図されたデータを絶対的に取得するようにプログラムを組むのは不可能ですね。
    \rは改行以外に含まないと仮定していいならできますが。
    ある程度で妥協するしかないですね。

    StreamReader.ReadLineを使わずに、という手はあまり使いたくないですが、
    情報が削れちゃうので無理ですね。

    Readから独自にReadLineを作るのかな。
    その際、「\r\r\n」->「\r\n」という変換では実装しないです。

    「\r」->「」として「\n」のみを改行として扱う、
    というように作ると思います。
    (HTTPと同じように。)
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19192  Re[6]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン -(2008/05/20(Tue) 23:23:18)
    No19187 (れい さん) に返信
    > 1 そんなところを気にしなくていいようなプログラムにする
    > というのが最初かな?

    例えば今回の事例では?

    > でも、この\n->\r\nは不可逆ですから
    > 本来意図されたデータを絶対的に取得するようにプログラムを組むのは不可能ですね。
    > \rは改行以外に含まないと仮定していいならできますが。
    > ある程度で妥協するしかないですね。

    俺なら、\r\r\n と来たら、それは \r\n と出したかったものだと解釈しちゃいますけどね。

    > 「\r」->「」として「\n」のみを改行として扱う、
    > というように作ると思います。
    > (HTTPと同じように。)

    HTTP は \r\n ですよ?
    HTML / XML は \n ですけど。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19200  Re[7]: Processの標準出力をリアルタイム取得
□投稿者/ れい -(2008/05/21(Wed) 00:03:55)
    2008/05/21(Wed) 00:06:26 編集(投稿者)

    No19192 (シャノン さん) に返信
    > 例えば今回の事例では?

    今回はデータを表示するだけです。
    意味は人間が解釈するわけですから、余計な空白があっても何の問題もありません。
    なので「何もしない」です。

    (人間は入力に寛容ですねぇ)

    > 俺なら、\r\r\n と来たら、それは \r\n と出したかったものだと解釈しちゃいますけどね。

    まぁそれもアリです。
    積極的に否定はしません。

    > HTTP は \r\n ですよ?
    > HTML / XML は \n ですけど。

    おおっと。また大切な説明が足りないですね。

    RFC2616 19.3 Tolerant Applications
    において、受信側では\rを無視して\nを改行とみなす実装が推奨されています。
    (特に根拠は書いてないのが問題ですが。)

    そんなわけで、
    「\r\r\n」を「\r\n」に置換するではなく、
    全ての「\r」を無視する、という選択を私なら取ると思います。

    そのほうがプログラムも楽で速いですし。

    #「早い」を「速い」に修正。
    #プログラムが「はやい」場合は「速い」ですよね?
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19202  Re[8]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン -(2008/05/21(Wed) 00:39:24)
    No19200 (れい さん) に返信
    > 今回はデータを表示するだけです。
    > 意味は人間が解釈するわけですから、余計な空白があっても何の問題もありません。
    > なので「何もしない」です。
    >
    > (人間は入力に寛容ですねぇ)

    なるほど。
    それで問題がないならそれもいいでしょうね。

    > RFC2616 19.3 Tolerant Applications
    > において、受信側では\rを無視して\nを改行とみなす実装が推奨されています。
    > (特に根拠は書いてないのが問題ですが。)
    >
    > そんなわけで、
    > 「\r\r\n」を「\r\n」に置換するではなく、
    > 全ての「\r」を無視する、という選択を私なら取ると思います。

    ふーむ。なるほど。
    どうにも、「理想的な方法」というのは思いつきませんね。
    どの方法も一長一短でしょうね。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19204  Re[9]: Processの標準出力をリアルタイム取得
□投稿者/ れい -(2008/05/21(Wed) 01:40:53)
    No19202 (シャノン さん) に返信
    > ふーむ。なるほど。
    > どうにも、「理想的な方法」というのは思いつきませんね。
    > どの方法も一長一短でしょうね。

    そうですね。
    絶対に元に戻せない変形が行われているわけですから。
    そのときに応じて適切なものを選ばざるを得ない。
    なるべく広範につかえてプログラムが楽なものが良いですが、
    状況次第、価値観次第。

    そういう時は他の方法の「あら」を探して批判するのがよいです。
    よいと信じてる方法の欠点はなかなか思いつかないものですから。

    なので「\r\r\n->\r\n」を批判すると…

    もし万が一借りに、2回改行コード変換が入っちゃったとすると
    「\r\r\r\n」みたいな改行コードになりますがそれに対応できませんよ!

    FTPでダウンロードしてそれをパイプでテキストに落としたりとか。(無い
    3回はいっちゃう場合もありえますよ?(無い

    「s/\r?\n/\r\n」にするなら対応できます。
    でもそれなら「s/\r*\n/\r\n」でいいでしょう?

    もういっそ「s/\r//」でいいじゃん、というわけですが。

    「s/\r//」の問題点はないですかね?

    旧Macで改行がなくなっちゃうというのがありますね。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

■19086  Re[1]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン -(2008/05/20(Tue) 10:55:26)
    No19072 (鶏唐揚 さん) に返信
    
    .NET Framework 1.1 でもできる範囲のコードで。
    
    class AsyncArgument
    {
        public Process process;
        public Stream stream;
        public byte[] buffer;
    }
    
    private static void Ping2()
    {
        using (Process p = new Process())
        {
            p.StartInfo.FileName = "ping.exe";
            p.StartInfo.Arguments = "127.0.0.1";
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
    
            p.Start();
    
            byte[] outputBuffer = new byte[1024];
            AsyncArgument aa = new AsyncArgument();
            aa.process = p;
            aa.stream = p.StandardOutput.BaseStream;
            aa.buffer = outputBuffer;
    
            aa.stream.BeginRead(outputBuffer, 0, 1024, StandardOutputCallback, aa);
            p.WaitForExit();
        }
    
        Console.WriteLine();
        Console.WriteLine("Complete");
    }
    
    static void StandardOutputCallback(IAsyncResult result)
    {
        AsyncArgument aa = result.AsyncState as AsyncArgument;
        int count = aa.stream.EndRead(result);
    
        string output = Console.OutputEncoding.GetString(aa.buffer, 0, count);
        if (!string.IsNullOrEmpty(output))
        {
            Console.WriteLine(output);
        }
    
        if (!aa.process.HasExited)
        {
            aa.stream.BeginRead(aa.buffer, 0, 1024, StandardOutputCallback, aa);
        }
    }
    
    しかし出力は細切れになってしまう。
記事No.19072 のレス /過去ログ37より / 関連記事表示
削除チェック/

次の20件>

<< 0 | 1 >>

パスワード/

- Child Tree -