2011-02-08 17 views
6

इस विषम ध्वनि शीर्षक के लिए खेद है ...स्ट्रीम में "एंटर कुंजी दबाएं" कैसे लिखें?

मेरे पास निम्न स्थिति है: मैं चाहता हूं कि मेरा जावा प्रोग्राम बाहरी कंसोल से बातचीत करे। उस कंसोल पर अलग-अलग आदेशों को "भेजने" के लिए, मुझे सामान्य कंसोल पर "एंटर दबाए गए" को अनुकरण करने की आवश्यकता है। मैं जो चाहता हूं उसे स्पष्ट करने के लिए, कल्पना करें कि MySQL के पास कोई अन्य एपीआई नहीं है और मुझे कंसोल के माध्यम से बातचीत करने की आवश्यकता होगी। हालांकि यह मेरी वास्तविक समस्या नहीं है, यह काफी करीब है।

मैं निम्नलिखित कोड है:

 String command = "/usr/local/mysql/bin/mysql"; 
     Process child = Runtime.getRuntime().exec(command); 

     StreamGobbler gobbler = new StreamGobbler(child.getInputStream()); 
     gobbler.start(); 

     BufferedWriter out = new BufferedWriter(new OutputStreamWriter(child.getOutputStream())); 
     out.write("help"); 
     // here enter key needs to be pressed 
     out.flush(); 
     // out.close(); 

तो out.close() को कॉल निष्पादित, सब कुछ ठीक है। लेकिन निश्चित रूप से, इस तरह से मैं केवल एक ही आदेश भेज सकता हूं, जो मैं नहीं चाहता हूं। लेकिन अगर out.close() छोड़ा गया है, तो दूसरा प्रोग्राम कभी भी कमांड निष्पादित नहीं करता है। मेरा अनुमान है कि यह अभी भी "खत्म" करने के लिए आदेश की प्रतीक्षा करता है, जो सामान्य कंसोल पर एंटर दबाकर किया जाएगा। out.write(System.getProperty("line.separator")); और out.newLine(); (जो समान हैं) समस्या को हल नहीं करते हैं, न ही out.write("\r\n"); और out.write((char) 26); (EOF)।

बेशक, यह हो सकता है कि मैं इसे पूरी तरह से गलत कर रहा हूं (यानी गलत दृष्टिकोण)। तो मैं सही दिशा में एक सूचक की सराहना करता हूं ...

इस अत्यधिक सराहना की कोई मदद।

+1

आपको मानक आउटपुट ** और ** मानक त्रुटि आउटपुट स्ट्रीम का उपभोग करना चाहिए। इन धाराओं पर आपको क्या मिलता है? –

+1

आप किस प्रणाली पर हैं? आप यूनिक्स पथ का उपयोग करते हैं, लेकिन विंडोज ईओएफ (Ctrl-Z = 26) का प्रयास किया? यूनिक्स ईओएफ Ctrl-D (= 4) है, लेकिन यह निश्चित रूप से भेजने के लिए सही बात नहीं है। –

+0

@ मार्क पीटर्स: क्षमा करें, मुझे त्रुटि आउटपुट स्ट्रीम के लिए भी एक गोबेलर जोड़ा जाना चाहिए था, लेकिन दोनों धाराओं को कुछ भी प्राप्त नहीं होता है जब तक कि 'out.close()' को इंगित नहीं किया जाता है। @ सेर्गेई टेचेनोव: मैं मैक पर काम करता हूं, और Ctrl-D या तो काम नहीं करता है, लेकिन इसे इंगित करने के लिए धन्यवाद। – roesslerj

उत्तर

7

निम्नलिखित कोड दोनों विंडोज 7 जावा 1.6.0_23 और Ubuntu 8.04 पर जावा 1.6.0_22 का उपयोग कर का उपयोग करने पर ठीक काम करता है:

public class Laj { 

    private static class ReadingThread extends Thread { 
    private final InputStream inputStream; 
    private final String name; 

    public ReadingThread(InputStream inputStream, String name) { 
     this.inputStream = inputStream; 
     this.name = name; 
    } 

    public void run() { 
     try { 
     BufferedReader in = new BufferedReader(
      new InputStreamReader(inputStream)); 
     for (String s = in.readLine(); s != null; s = in.readLine()) { 
      System.console().writer().println(name + ": " + s); 
     } 
     } catch (Exception e) { 
     e.printStackTrace(); 
     } 
    } 
    } 

    public static void main(String[] args) throws Exception { 
    String command = "psql -U archadm arch"; 
    final Process child = Runtime.getRuntime().exec(command); 
    new ReadingThread(child.getInputStream(), "out").start(); 
    new ReadingThread(child.getErrorStream(), "err").start(); 
    BufferedWriter out = new BufferedWriter(
     new OutputStreamWriter(child.getOutputStream())); 
    out.write("\\h"); 
    out.newLine(); 
    out.flush(); 
    out.write("\\q"); 
    out.newLine(); 
    out.flush(); 
    } 

} 

न्यू लाइन() है मंच लाइन विभाजक लिखने के समान ही। जैसा कि कोई उम्मीद करेगा, यह "आउट:" से पहले मदद करता है, फिर बाहर निकलता है। अगर मैं "\ q" नहीं भेजता, तो यह बाहर निकलता नहीं है (जाहिर है) लेकिन अभी भी प्रिंट प्रिंट करता है। प्लेटफॉर्म लाइन विभाजक के बजाय "\ r \ n" या "\ r" का उपयोग करना मेरे लिए एक अच्छा विचार नहीं दिखता है, क्योंकि ऐसी कमांड लाइन उपयोगिताओं को आमतौर पर पता चल जाएगा कि उन्हें टर्मिनल से इनपुट नहीं मिलता है और लगता है यह मूल पाठ प्रारूप में है (सोचें "psql < script.sql")। अच्छे सॉफ़्टवेयर को उचित रूप से सभी उचित रेखा समाप्ति का पता लगाना चाहिए और स्वीकार करना चाहिए।

+0

अपना उदाहरण पोस्ट करने के लिए धन्यवाद। चूंकि आप मूल रूप से मेरे जैसा ही करते हैं, इसलिए अंतर संभवतः कॉल की गई प्रक्रिया या अंतर्निहित ओएस (मेरे मामले में मैकओएक्सएक्स) या जावा संस्करण में भी है। मैं देखूंगा कि मैं क्या ढूंढ सकता हूं, आपके उत्तर के लिए धन्यवाद! – roesslerj

+0

@roesslerj, आपको अभी भी पहले stderr की जांच करनी चाहिए। एक मूर्खतापूर्ण बग हो सकता है जो आदेश के सामान्य संचालन को रोकता है। या शायद यह, stderr में चेतावनी और अवरुद्ध हो जाता है किसी प्रकार का लिखने के लिए क्योंकि stderr unbuffered है कोशिश कर रहा है, और दूसरी तरफ (अपनी प्रक्रिया) कुछ भी नहीं पढ़ रहे हैं। –

+0

कोड के इस टुकड़े को वितरित करने के लिए धन्यवाद। ऐसा लगता है कि अपने कोड मेरे लिए काम करता साथ ही ... और मुझे 'StreamGobbler' वर्ग (जो आपके सिफारिश के रूप में मैं दोनों stdout के लिए इस्तेमाल की छोड़े गए कोड में एक मूर्ख गलती थी कि और stderr ... बस एक छोटी सी टिप्पणी:।। 'out.write (System.getProperty (" line.separator "));' 'out.newLine() कॉल करने जैसा ही में परिणाम;' – roesslerj

0

out.write((char) 13) के बारे में क्या? यह Wikipedia आलेख देखें। मेरे पास यह परीक्षण करने के लिए पर्याप्त कोड नहीं है।

+0

जावा में कैरिज रिटर्न कैरेक्टर '\ r' के साथ दर्शाया गया है, इसलिए मैंने पहले ही यह कोशिश की है (टेक्स्ट देखें), लेकिन इनपुट के लिए अभी भी धन्यवाद। – roesslerj

0

इस एपीआई

http://download.oracle.com/javase/6/docs/api/java/io/Console.html

मेरे अनुभव से में देखने का प्रयास करना चाह सकते हैं, मैं प्रक्रिया एपीआई से किसी चल रही प्रक्रिया की तुलना में अधिक कुछ भी करने की कोशिश की कभी नहीं किया है। ऐसा लगता है कि आप कई कमांड दर्ज करना चाहते हैं, मुझे लगता है कि यह एपीआई आपको ऐसा करने दे सकती है।

संपादित करें: आगे की सहायता के लिए इस पर एक ट्यूटोरियल मिला। http://download.oracle.com/javase/tutorial/essential/io/cl.html

आशा इस मदद करता है,

+2

मुझे शायद यह गलत हो रहा है, लेकिन जब आप एक इंटरेक्टिव कंसोल लिखते हैं तो यह एपीआई आपको जितना चाहें उतना लगता है। लेकिन यह वह नहीं है जो मैं करना चाहता हूं; मैं एक बाहरी प्रक्रिया के रूप में इस तरह के एक सांत्वना के साथ बातचीत करने की है। – roesslerj

संबंधित मुद्दे