2013-03-21 16 views
6

Delphiコンソールアプリケーションからstdoutに書き込む方法を教えてください。Delphiでバイナリデータをstdoutに書き込む方法は?

ここに私が試したことがあります。

program ConsoleOut; 
{$APPTYPE CONSOLE} 
uses 
    Classes, Windows, SysUtils; 

var 
    S: TMemoryStream; 
    OutputStream: THandleStream; 
    ss: string; 
    Buffer: PByte; 
    i: Integer; 
begin 
    S := TMemoryStream.Create; 
    S.LoadFromFile('1.jpg'); 
    S.Seek(0, soFromBeginning); 

    //Am I right that from now on writing to OutputStream will write to stdout? 
    OutputStream := THandleStream.Create(GetStdHandle(STD_OUTPUT_HANDLE)); 

    GetMem(Buffer, S.Size); 
    S.ReadBuffer(Buffer^, S.Size); 
    i := OutputStream.Write(Buffer^, S.Size); //i = 0 here for some reason 
    FreeMem(Buffer, S.Size); 

    Writeln(i, ' byte written to output'); 
    Readln(ss); //Don't exit app to read previous line 
    S.Free; 
end. 

をしかし、それが失敗した何らかの理由:私はそれが標準出力をコンソールにディスクと出力からファイルを読み取るために、私は見つけることができるに関する情報によると、この簡単なテストアプリケーションを装備しています。あなたは私をstdoutに書く正しい方法に向かわせてください。

+0

奇妙な理由コンソールにバイナリノイズを書きたいのですが?あなたはスピーチのテキストについて言及します。なぜ名前付きパイプはありませんか? –

+1

名前付きパイプはstdoutに対してどのような利点がありますか? – Kromster

+0

Windowsでは、ユーザーインターフェイスの代わりに深刻なデータ転送用に設計されています。 Unix標準出力は、匿名データパイプとして日常的に使用されています。 DosとWindowsはこれを日常的に使用していません。あなたが学んだように。 –

答えて

7

あなたのアプローチは健全です。しかし、stdoutがコンソールに接続されていれば、コードは失敗します。ストリーム書込み以下GetLastErrorへの呼び出しがエラーコードERROR_NOT_ENOUGH_MEMORY明らかにする:

ない十分なストレージを、このコマンドを処理することが可能です。

stdoutをファイルにリダイレクトすると、コードは正常に動作します。そして確かにバイナリデータをコンソールに流したくはありません。それは、コンソールに読めないコンテンツを入れて、コンピュータが騒々しく鳴るようにするだけです!

コンソールに出力する必要がある場合は、コンソールデバイスバッファの容量を調べ、適切なサイズのチャンクで書き込む必要があります。私はあなたがどうやってそれをやっていくのか分からないと告白しなければならない。あなたは試行錯誤をすることができますが、それは私にとって魅力的ではありません。おそらく、情報を見つけるためにコンソールを照会する方法があります。

WriteConsoleのドキュメントを見ると、64Kが上限であるようです。そして、実際にあなたのハンドルストリームにスペースを書くと、私は64Kを一度に書くことができます。しかし、生のJPEGバイナリデータを書き込むと、早く分かります。だから私はそれも問題の一部だと思う - JPEGをコンソールにダンプしないでください。

他の1コメント。ファイルの内容をメモリストリームに読み込むので、中間バッファを割り当てる必要はありません。直接S.Memory^と書くことができます。

+1

ヒントのおかげで、私はコンソールが空であれば動作していないが、stdoutをファイル( "appname.exe> out.jpg")にリダイレクトするとうまくいきました。 – Kromster

+1

脇役に:私は生成し、stdoutにテキストを音声に出力する必要があるので、バイナリデータとその多く(数MB)です。しかし、あなたの答えは多くの面をカバーしているので、他の人には役に立ちますので、カットしないでください) – Kromster

+0

@KromStern:あなたの最後のコメントは理にかなっていません。 'text to speech to stdout'を実行して' stdout'をファイルにリダイレクトする場合、単に 'text to speech to file'を実行して' stdout'仲介人を省略することができます。出力をファイルにすぐにリダイレクトするためのコンソールへの書き込みのポイントはありません。 –

関連する問題