我希望 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 , Golang和 Perl .
关于java - 如何检查 Java 程序的输入/输出流是否连接到终端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1403772/