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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (110)

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

提问于
用户回答回答于

System.console()将返回应用程序连接的控制台(如果已连接),否则返回null

用户回答回答于

System.console()vs isatty()

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

Java的System.console()和C的isatty()之间的区别可以在下面的case-breakdown(我们将数据传入/传出假设的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-checking。我想知道Java的某些目标操作系统是否支持它。

使用JNI调用isatty()

从技术上讲,它可以用Java(如stephen-c @指出)和一些相当简单的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;
}

扫码关注云+社区

领取腾讯云代金券