Java プログラムに、使用状況に応じて異なるデフォルト設定 (詳細度、サポートされている場合は色付き出力) を持たせたいと考えています。C には、ファイル記述子が端末に接続されている場合は 1 を返し、そうでない場合は 0 を返す isatty() 関数があります。Java にはこれに相当するものはありますか? InputStream または PrintStream の JavaDoc には何も記載されていません。
ベストアンサー1
System.console() と isatty()
System.console() は、@Bombe がすでに述べたように、コンソールの接続性をチェックする単純なユースケースで機能します。ただし、System.console() の問題は、コンソールに接続されているのが STDIN か STDOUT (または両方、あるいはどちらでもない) か判断できないことです。
Javaのシステム.コンソール()そしてCのisatty()これは、次のケースの内訳で説明できます (ここでは、仮想の Foo.class との間でデータをパイプします)。
1) STDINとSTDOUTはttyである
%> java Foo
System.console() => <Console instance>
isatty(STDIN_FILENO) => 1
isatty(STDOUT_FILENO) => 1
2) STDOUTはttyです
%> echo foo | java Foo
System.console() => null
isatty(STDIN_FILENO) => 0
isatty(STDOUT_FILENO) => 1
3) STDINはttyです
%> java Foo | cat
System.console() => null
isatty(STDIN_FILENO) => 1
isatty(STDOUT_FILENO) => 0
4) STDINもSTDOUTもttyではない
%> echo foo | java Foo | cat
System.console() => null
isatty(STDIN_FILENO) => 0
isatty(STDOUT_FILENO) => 0
Java がなぜより優れた tty チェックをサポートしないのかはわかりません。Java の対象 OS の一部がそれをサポートしていないのではないかと思います。
JNI を使用して isatty() を呼び出す
技術的にははこれをJavaで実行することは可能です(stephen-c@が指摘したように)かなりシンプルなJNIただし、そうするとアプリケーションが C コードに依存することになり、他のシステムに移植できなくなる可能性があります。一部の人がその方法を望まないのは理解できます。
JNI がどのようになるかの簡単な例 (多くの詳細は省略) を以下に示します。
ジャワ:tty/TtyUtils.java
public class TtyUtils {
static {
System.loadLibrary("ttyutils");
}
// FileDescriptor 0 for STDIN, 1 for STDOUT
public native static boolean isTty(int fileDescriptor);
}
C:ttyutils.c(一致することを前提としていますttyutils.h)、にコンパイルlibttyutils.so
#include <jni.h>
#include <unistd.h>
JNIEXPORT jboolean JNICALL Java_tty_TtyUtils_isTty
(JNIEnv *env, jclass cls, jint fileDescriptor) {
return isatty(fileDescriptor)? JNI_TRUE: JNI_FALSE;
}
他の言語:
他の言語を使うオプションがある場合、私が思いつく限りのほとんどの言語はttyチェックをサポートしています。しかし、あなたが質問したということは、おそらくすでにご存知でしょう。私が思いつく最初の言語は(C/C++を除いて)ルビー、パイソン、Go言語そしてパール。