2009-06-30 6 views
83

자바에 입력 된 사용자로 콘솔에서 하나의 문자를 읽을 수있는 쉬운 방법이 있나요? 가능한가? 나는 이러한 방법으로 시도했지만 그들은 모두 키 입력 눌러 사용자 대기 : 나는 가 입력 할 때까지 System.in은 사용자 입력의 인식이 아니라고 생각하기 시작하고Java에서 콘솔에서 단일 문자를 읽는 방법 (사용자가 입력 할 때)?

char tmp = (char) System.in.read(); 
char tmp = (char) new InputStreamReader(System.in).read(); 
char tmp = (char) System.console().reader().read();   // Java 6 

을 눌렀다.

답변

50

"쿡"모드 (입력 키가 필요한 행 편집 필요)와 달리 콘솔을 "원시"모드 (라인 편집 생략 및 입력 키 필요 없음)에 넣으십시오. UNIX 시스템에서 ' stty '명령은 모드를 변경할 수 있습니다.

이제 자바에 대한 ... Non blocking console input in Python and Java를 참조하십시오. 발췌 :

프로그램이 기반 콘솔을해야하는 경우 문자 모드로 라인 모드의 을 터미널을 전환하고, 당신의 프로그램이 종료하기 전에 복원 기억해야 . 시스템에서이 작업을 수행 할 수있는 이동식 장치가 없습니다. 제안의

하나는 JNI를 사용하는 것입니다. 다시 말하지만, 이식성이 좋지 않습니다. 스레드 끝에있는 또 다른 제안은 위의 게시물과 공통적으로 jCurses을 사용하는 것입니다.

+4

JCurses 매우 이식 할 수 없습니다 중 하나 .... JCurses의 README에서 "JCurses는 두 부분으로 구성 플랫폼 이서 독립적 인 부분 및 플랫폼 이서 의존 첫 번째 부분에서 사용할 수있는 기본 입력 및 출력 작업을 만드는 네이티브 공유 라이브러리로 구성됩니다. " –

+2

@RyanFernandes는 나에게 꽤 휴대용 소리가 들린다 - 여러 시스템에서 실행할 수있는 (다른 의존성을 사용하는) 단일 도구 – Antoniossss

20

당신은 원시 모드로 콘솔을 노크해야합니다. 거기에는 플랫폼 독립적 인 방법이 없습니다. 유닉스 시스템에서

jCurses might be interesting, though.이 작동 될 수 있습니다

String[] cmd = {"/bin/sh", "-c", "stty raw </dev/tty"}; 
    Runtime.getRuntime().exec(cmd).waitFor(); 

For example, if you want to take into account the time between keystrokes, here's sample code to get there.

+0

Linux에서 저에게 잘 작동했습니다. – MrSmith42

+0

Mac에서도 잘 작동합니다. 'stty cooked Kelvin

+0

"예를 들어 ..."링크가 이제 종료되었습니다. –

13

자바 콘솔에서 원시 문자를 읽을 수없는 휴대용 방법은 없습니다.

어떤 플랫폼에 따라 해결 방법은 위에서 제시되었다. 하지만 실제로 휴대하기 위해서는 콘솔 모드를 포기하고 윈도우 모드를 사용해야합니다. AWT 또는 Swing.

+11

Mono (또는 CLR)에 모든 플랫폼에서 작동하는'System.Console.ReadKey'가있는 이유를 저는 이해하지 못합니다. Java는 또한 플랫폼에 종속적 인 라이브러리 및 구현을 사용하는 모든 플랫폼에 JVM 및 JRE를 배포하므로 아무런 변명의 여지가 없습니다. –

6

Windows 및 Unix/Linux의 운영 체제 기능을 호출하기 위해 JNA을 사용하는 Java 클래스 RawConsoleInput을 작성했습니다.

  • 는 Windows에서이 _kbhit() 및 MSVCRT.DLL에서 _getwch() 사용합니다.
  • Unix에서는 tcsetattr()을 사용하여 콘솔을 비표준 모드 (System.in.available())로 전환하여 데이터를 사용할 수 있는지 확인하고 System.in.read()은 콘솔에서 바이트를 읽습니다. CharsetDecoder은 바이트를 문자로 변환하는 데 사용됩니다.

가 지원하는 비 차단 입력 원시 모드 법선 모드 입력 혼합.

+0

테스트/스트레스 테스트를 얼마나 많이 받았습니까? –

+1

@QPaysTaxes 콘솔 입력에 대한 스트레스 테스트가 어렵습니다. 이 경우 다양한 환경 (다른 Windows/Linux 버전, 64/32 비트, SSH, 텔넷, 직렬 포트 또는 데스크탑 콘솔 등을 통한 Linux)에서 테스트하는 것이 더 중요하다고 생각합니다. 지금까지는 개인 테스트 도구에서만 사용합니다. 그러나 소스 코드는 Jansi를 사용하는 JLine2와 같은 다른 솔루션에 비해 상대적으로 작습니다. 그래서 잘못 될 수있는 것은별로 없습니다. JLine2는 차단하지 않고 단일 문자 입력을 지원하지 않기 때문에 작성했습니다. –

+0

그건 내가 스트레스 테스트를 거쳤습니다. 아마 잘못된 단어 일 겁니다. 내 잘못이야. 어쨌든, 좋은! 나는 H^H^H^H^H^H를 도난당했습니다. 학교 프로젝트에 그것을 사용하고 그것을 도왔습니다. –

0

사용 jline3 :

예 :

Terminal terminal = TerminalBuilder.builder() 
    .jna(true) 
    .system(true) 
    .build(); 

// raw mode means we get keypresses rather than line buffered input 
terminal.enterRawMode(); 
reader = terminal .reader(); 
... 
int read = reader.read(); 
.... 
reader.close(); 
terminal.close(); 
관련 문제