java - 如何检查 Java 程序的输入/输出流是否连接到终端?

标签 java console terminal

我希望 Java 程序根据其用途具有不同的默认设置(详细程度,可能支持彩色输出)。在 C 中,有一个 isatty() 函数,如果文件描述符连接到终端,则返回 1,否则返回 0。在 Java 中是否有等价物?我在 JavaDoc 中没有看到 InputStream 或 PrintStream 的任何内容。

最佳答案

System.console() 与 isatty()

System.console(),正如@Bombe 已经提到的,适用于检查控制台连接的简单用例。然而,System.console() 的问题在于它无法让您确定连接到控制台的是 STDIN 还是 STDOUT(或两者都或两者都不是)。

Java 的 System.console() 之间的区别和 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) 标准输入是 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的某些目标操作系统是否不支持它。

使用JNI调用isatty()

技术上 可以在 Java 中做到这一点(正如 stephen-c@ 指出的那样),使用一些 fairly simple JNI ,但它会使您的应用程序依赖于可能无法移植到其他系统的 C 代码。我可以理解有些人可能不想去那里。

JNI 外观的简单示例(忽略了很多细节):

Java: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-checking。但是,既然你问了这个问题,你可能已经知道了。我首先想到的(除了 C/C++)是 Ruby , Python , GolangPerl .

关于java - 如何检查 Java 程序的输入/输出流是否连接到终端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1403772/

相关文章:

java - Java中Eratosthenes的多线程分段筛分

java - 将 JavaEE 应用程序角色映射到 weblogic 安全角色

Java nextLine 在套接字上被阻塞

java - Android - 在第一次通话后启动 Intent

java - 触发 Java GUI 更新

c++ - 如何将特定行的用户输入打印到控制台 (C++)

C++ 忽略某些输出的 cout 重定向

c - 使用 makefile 在 Xcode 4 中运行 C 程序

macos - OSX 10.11 El Capitan-设置启动设备属性不起作用

bash - 如何使我的 shell 脚本可执行