如何检查 Java 程序的输入/输出流是否连接到终端? [英] How can I check if a Java program's input/output streams are connected to a terminal?

查看:17
本文介绍了如何检查 Java 程序的输入/输出流是否连接到终端?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like a Java program to have different default settings (verbosity, possibly colored output where supported) depending on its use. In C, there is an isatty() function which will return 1 if a file descriptor is connected to a terminal, and 0 otherwise. Is there an equivalent for this in Java? I haven't seen anything in the JavaDoc for InputStream or PrintStream.

推荐答案

System.console() vs isatty()

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

System.console() vs isatty()

System.console(), as already mentioned by @Bombe, works for simple use cases of checking console-connectedness. The problem with System.console() however, is that it doesn't let you determine whether it's STDIN or STDOUT (or both or neither) that is connected to a console.

Java的System.console()的区别 和 C 的 isatty() 可以在以下案例分解中说明(我们将数据通过管道传入/传出假设的 Foo.class):

The difference between Java's System.console() and C's isatty() can be illustrated in the following case-breakdown (where we pipe data to/from a hypothetical Foo.class):

1) STDIN 和 STDOUT 是 tty

1) STDIN and STDOUT are tty

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

2) STDOUT 是 tty

2) STDOUT is tty

%> echo foo | java Foo
System.console() => null
isatty(STDIN_FILENO) => 0
isatty(STDOUT_FILENO) => 1

3) STDIN 是 tty

3) STDIN is tty

%> java Foo | cat
System.console() => null
isatty(STDIN_FILENO) => 1
isatty(STDOUT_FILENO) => 0

4) STDIN 和 STDOUT 都不是 tty

4) Neither STDIN nor STDOUT are tty

%> echo foo | java Foo | cat
System.console() => null
isatty(STDIN_FILENO) => 0
isatty(STDOUT_FILENO) => 0

我无法告诉您为什么 Java 不支持更好的 tty 检查.我想知道是否有一些 Java 的目标操作系统不支持它.

I can't tell you why Java doesn't support better tty-checking. I wonder if some of Java's target OS's don't support it.

技术上可以在 Java 中使用一些 相当简单的 JNI,但它会使您的应用程序依赖于可能无法移植到其他系统的 C 代码.我能理解有些人可能不想去那里.

It technically is possible to do this in Java (as stephen-c@ pointed out) with some fairly simple JNI, but it will make your application dependent on C-code that may not be portable to other systems. I can understand that some people may not want to go there.

JNI 外观的快速示例(掩盖了很多细节):

A quick example of what the JNI would look like (glossing over a lot of details):

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

C: ttyutils.c (assumes matching ttyutils.h), compiled to 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++)是 RubyPythonGolangPerl.

这篇关于如何检查 Java 程序的输入/输出流是否连接到终端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆