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

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

C# と VB.NET の入門サイト

Re[10]: Processの標準出力をリアルタイム取得 [1]


(過去ログ 37 を表示中)

[トピック内 38 記事 (21 - 38 表示)]  << 0 | 1 >>

■19134 / inTopicNo.21)  Re[5]: Processの標準出力をリアルタイム取得
  
□投稿者/ シャノン (437回)-(2008/05/20(Tue) 14:22:48)
No19131 (ネタ好き さん) に返信
> >pingが意図的に\rを出している、つまり仕様である可能性ももちろんありますが。
> >その場合理由が見えません。
> ほんとおかしな挙動ですよね。データの終了を判定するためにあるのかな?
> でも何パケット送るかはpingプログラムは周知しているはずですから意味が無いような・・・

いや、ネットワークの話じゃなくて。
コンソールに結果を出力するときの行末コードの話です。
ping が \r\n を出しているんでしょうね。

ちなみに、.NET Framework の Console.Out はバイナリモードのようです。
引用返信 編集キー/
■19141 / inTopicNo.22)  Re[6]: Processの標準出力をリアルタイム取得
□投稿者/ 鶏唐揚 (144回)-(2008/05/20(Tue) 14:34:10)
いつのまにか伸びていた…

様々なコード案ありがとうございます。
仕事と平行でチラチラ見てるので全然解析できてませんが、
採用するしないにかかわらず全部見ていきたいと思います

#たぶんこの中から選ぶか組み合わせたり改造したりして実装するので
 ここで解決させていただきます。
 Ping行末についての議論は続けてくださっても構いません。
 今回の件に少なからず関係しているのでw
解決済み
引用返信 編集キー/
■19147 / inTopicNo.23)  Re[6]: Processの標準出力をリアルタイム取得
□投稿者/ れい (561回)-(2008/05/20(Tue) 15:13:16)
バイナリ/テキストの話はCやC++の標準ライブラリの話です。
なので、

No19134 (シャノン さん) に返信
> コンソールに結果を出力するときの行末コードの話です。
> ping が \r\n を出しているんでしょうね。

pingのコードが\r\nを使っているので、
Executableが\r\r\nを出してしまっているのだと思います。

> ちなみに、.NET Framework の Console.Out はバイナリモードのようです。

.Netのストリームはバイナリ/テキストの区別はないでしょう。
文字コードとか、もっと大変なことがいっぱいありますから。

引用返信 編集キー/
■19149 / inTopicNo.24)  Re[7]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン (438回)-(2008/05/20(Tue) 15:34:25)
No19147 (れい さん) に返信
> バイナリ/テキストの話はCやC++の標準ライブラリの話です。
> なので、
>
> ■No19134 (シャノン さん) に返信
>>コンソールに結果を出力するときの行末コードの話です。
>>ping が \r\n を出しているんでしょうね。
>
> pingのコードが\r\nを使っているので、
> Executableが\r\r\nを出してしまっているのだと思います。
>
>>ちなみに、.NET Framework の Console.Out はバイナリモードのようです。
>
> .Netのストリームはバイナリ/テキストの区別はないでしょう。
> 文字コードとか、もっと大変なことがいっぱいありますから。

なんだか揚げ足取られているように感じてしまうナァ…
.NET の Console は \n -> \r\n 変換をせずにそのまま出しますよ、ということでバイナリモードと呼びました。
引用返信 編集キー/
■19153 / inTopicNo.25)  Re[7]: Processの標準出力をリアルタイム取得
□投稿者/ 渋木宏明(ひどり) (759回)-(2008/05/20(Tue) 15:54:38)
渋木宏明(ひどり) さんの Web サイト
>  Ping行末についての議論は続けてくださっても構いません。
>  今回の件に少なからず関係しているのでw

ちなみに、プログラムから Ping 相当の操作が行いたい、ってことなら、ping.exe の実行結果をキャプチャする以外にも方法はありますよ?
引用返信 編集キー/
■19154 / inTopicNo.26)  Re[8]: Processの標準出力をリアルタイム取得
□投稿者/ ネタ好き (307回)-(2008/05/20(Tue) 15:57:18)
No19153 (渋木宏明(ひどり) さん) に返信
>> Ping行末についての議論は続けてくださっても構いません。
>> 今回の件に少なからず関係しているのでw
>
> ちなみに、プログラムから Ping 相当の操作が行いたい、ってことなら、ping.exe の実行結果をキャプチャする以外にも方法はありますよ?

System.Net.NetworkInformation.Pingクラスの事かな?
もしくは自分でPingを実装するとか?
引用返信 編集キー/
■19155 / inTopicNo.27)  Re[9]: Processの標準出力をリアルタイム取得
□投稿者/ 鶏唐揚 (145回)-(2008/05/20(Tue) 16:05:55)
No19154 (ネタ好き さん) に返信
> ■No19153 (渋木宏明(ひどり) さん) に返信
> >> Ping行末についての議論は続けてくださっても構いません。
> >> 今回の件に少なからず関係しているのでw
>>
>>ちなみに、プログラムから Ping 相当の操作が行いたい、ってことなら、ping.exe の実行結果をキャプチャする以外にも方法はありますよ?
>
> System.Net.NetworkInformation.Pingクラスの事かな?
> もしくは自分でPingを実装するとか?
今回は一例として挙げただけで、Pingに限らずコンソールアプリの標準出力のリアルタイム取得が最終目的でした。
ただPing処理を行う場合は有用そうなので参考にさせていただきます。
情報ありがようございます
引用返信 編集キー/
■19159 / inTopicNo.28)  Re[8]: Processの標準出力をリアルタイム取得
□投稿者/ れい (562回)-(2008/05/20(Tue) 16:26:15)
No19149 (シャノン さん) に返信
> なんだか揚げ足取られているように感じてしまうナァ…
> .NET の Console は \n -> \r\n 変換をせずにそのまま出しますよ、ということでバイナリモードと呼びました。

あう。
すみませんでした。

シャノンさんに言ってるというよりは、
読んでる他の人にわかりやすいよう補足したつもりでした。

流し読みをするとテキストモードというのが存在していると勘違いする人がいるかなぁと思ったので。

正確に伝わらないことを危惧して補足した結果揚げ足取りに見えてしまう、
というのは今までもきっとありますね。

非難する気もからかう気も全く無いので、
揚げ足取りに見えるということは
1 細かい点にうるさくて
2 発言が非難がましい
のでしょうね。

私は理解力が低く、正確で細かくないと間違ってしまうので
細かいところにうるさいのは仕方ないとして。
それに細かい点の指摘はただの指摘ですから。

細かいことを言うときは特に表現に気をつけないといけないということですね。

難しいなぁ。
引用返信 編集キー/
■19171 / inTopicNo.29)  Re[7]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン (440回)-(2008/05/20(Tue) 17:58:29)
> ■No19134 (シャノン さん) に返信
>>コンソールに結果を出力するときの行末コードの話です。
>>ping が \r\n を出しているんでしょうね。
>
> pingのコードが\r\nを使っているので、
> Executableが\r\r\nを出してしまっているのだと思います。

今度から俺が C/C++ でアプリ作るときは、stdout は常にバイナリモードにしとこうかな…
引用返信 編集キー/
■19173 / inTopicNo.30)  Re[4]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン (441回)-(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 になってしまうコンソールアプリは少なくないことは想定できます。
引用返信 編集キー/
■19187 / inTopicNo.31)  Re[5]: Processの標準出力をリアルタイム取得
□投稿者/ れい (565回)-(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と同じように。)
引用返信 編集キー/
■19192 / inTopicNo.32)  Re[6]: Processの標準出力をリアルタイム取得
□投稿者/ シャノン (442回)-(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 ですけど。
引用返信 編集キー/
■19200 / inTopicNo.33)  Re[7]: Processの標準出力をリアルタイム取得
□投稿者/ れい (566回)-(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」を無視する、という選択を私なら取ると思います。

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

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

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

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

ふーむ。なるほど。
どうにも、「理想的な方法」というのは思いつきませんね。
どの方法も一長一短でしょうね。
引用返信 編集キー/
■19204 / inTopicNo.35)  Re[9]: Processの標準出力をリアルタイム取得
□投稿者/ れい (567回)-(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で改行がなくなっちゃうというのがありますね。
引用返信 編集キー/
■19208 / inTopicNo.36)  Re[8]: Processの標準出力をリアルタイム取得
□投稿者/ ネタ好き (311回)-(2008/05/21(Wed) 01:51:02)
ところで、この余分な文字コードはどのソフトが付加しているのでしょうか?
もしPing.exeならばUNIX系OSから見たら困った仕様です。
それとも、com.exe?何のためそんなことをしているのやら・・・
引用返信 編集キー/
■19209 / inTopicNo.37)  Re[9]: Processの標準出力をリアルタイム取得
□投稿者/ れい (568回)-(2008/05/21(Wed) 03:20:16)
No19208 (ネタ好き さん) に返信
> ところで、この余分な文字コードはどのソフトが付加しているのでしょうか?
> もしPing.exeならばUNIX系OSから見たら困った仕様です。
> それとも、com.exe?何のためそんなことをしているのやら・・・

うーむ。
これだけ書いてもまだ誤解する人が。

おそらくですが、
pingのソースは"\r\n"となっていて、
ping.exeにリンクされてるライブラリが付加しています。

ping.exeの出力をパイプで開くと\r\r\nが得られるので、シェルも関係ありません。

念のため言っておくと、ネットワークとは一切関係ありません。
unixとかも関係ありません。
Windowsのpingの標準出力周りの実装の話です。

引用返信 編集キー/
■19212 / inTopicNo.38)  Re[10]: Processの標準出力をリアルタイム取得
□投稿者/ ネタ好き (312回)-(2008/05/21(Wed) 09:06:57)
2008/05/21(Wed) 09:18:55 編集(投稿者)

No19209 (れい さん) に返信
いやぁ、申しわけない。私はUNIX系OSも勉強しているので、
はっきりと文字コードが出来る場所を特定しておきたいのです。
そうした疑問をはっきりしておかないと、
UNIX系OSのネットワークプログラミング際に思わぬ事に遭遇すると思うのです。
例えば、WindowsとLinuxの共通で動くプログラムをC言語で作る時とかです。
下手な文字コード処理プログラムを書いてしまうとWindowsではOKでも、Linuxでは変な処理結果が生まれてしまいます。
引用返信 編集キー/

<前の20件
トピック内ページ移動 / << 0 | 1 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -