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

有帮助吗?

解决方案

System.console()将返回应用程序连接的控制台(如果已连接),否则返回 null 。 (请注意,它只能从JDK 6开始使用。)

其他提示

System.console()vs isatty()

@Bombe已经提到的System.console()适用于检查控制台连接性的简单用例。但是,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)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;
}

其他语言:

如果您可以选择使用其他语言,我可以考虑支持tty检查的大多数其他语言。但是,既然你问了这个问题,你可能已经知道了。我想到的第一个问题(除了C / C ++)是 Ruby Python Golang Perl的

简短的回答是标准Java中没有“isatty”的直接等价物。自从Java Bug数据库中出现了类似的内容, RFE 1997年,但只有 1 一个可怜的投票。

理论上,您可以使用JNI魔法实现'isatty'。但这引入了各种潜在的问题。我甚至不打算自己这样做......


1 - 在Oracle接管Sun的时候,Java错误的修复就消失了。

您可以使用 jnr-posix 库调用原生posix方法来自Java:

import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import java.io.FileDescriptor;

POSIX posix = POSIXFactory.getPOSIX();

posix.isatty(FileDescriptor.out);

如果您不想自己编译C源代码,可以使用Jansi库。它比jnr-posix

小很多
<dependency>
  <groupId>org.fusesource.jansi</groupId>
  <artifactId>jansi</artifactId>
  <version>1.17.1</version>
</dependency>

...

import static org.fusesource.jansi.internal.CLibrary.isatty;

...

System.out.println( isatty(STDIN_FILENO) );
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top