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

2024-03-27

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


System.console() 与 isatty()

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

Java 的区别系统.控制台() http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#console%28%29和C的isatty() http://man7.org/linux/man-pages/man3/isatty.3.html%20%22isatty%28%29可以通过以下案例分解来说明(我们通过管道将数据传入/传出假设的 Foo.class):

1) STDIN 和 STDOUT 是 tty

%> java Foo
System.console() => <Console instance>
isatty(STDIN_FILENO) => 1
isatty(STDOUT_FILENO) => 1

2)标准输出是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 的目标操作系统是否不支持它。

使用 JNI 调用 isatty()

从技术上来说is可以在Java中使用一些方法来做到这一点(正如stephen-c@指出的)相当简单的 JNI http://jonisalonen.com/2012/calling-c-from-java-is-easy/,但它会使您的应用程序依赖于可能无法移植到其他系统的 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 检查。但是,既然你问了这个问题,你可能已经知道了。我首先想到的是(除了 C/C++)Ruby http://www.ruby-doc.org/core-2.1.1/IO.html#method-i-tty-3F, Python https://docs.python.org/2/library/os.html#os.isatty, Golang http://godoc.org/code.google.com/p/go.crypto/ssh/terminal#IsTerminal and Perl http://perldoc.perl.org/POSIX.html#isatty.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐