Javaプログラムの入出力ストリームが端末に接続されているかどうかを確認するにはどうすればよいですか? 質問する

Javaプログラムの入出力ストリームが端末に接続されているかどうかを確認するにはどうすればよいですか? 質問する

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言語そしてパール

おすすめ記事