2011-10-03 6 views
7

मुझे जावा विधि की आवश्यकता है जो कमांड प्रॉम्प्ट आउटपुट को पढ़ेगा और इसे जावा में पढ़ने के लिए स्ट्रिंग में संग्रहीत करेगा।जावा में स्ट्रिंग करने के लिए कमांड प्रॉम्प्ट आउटपुट प्राप्त करें

यह मेरे पास अभी तक है लेकिन सही काम नहीं कर रहा है।

public void testGetOutput() { 
    System.out.println("\n\n****This is the testGetOutput Method!****"); 
    String s = null; 
    String query = "dir " + this.desktop; 
    try { 
     Runtime runtime = Runtime.getRuntime(); 
     InputStream input = runtime.exec("cmd /c " + query).getInputStream(); 
     BufferedInputStream buffer = new BufferedInputStream(input); 
     BufferedReader commandResult = new BufferedReader(new InputStreamReader(buffer)); 
     String line = ""; 
     try { 
      while ((line = commandResult.readLine()) != null) { 
       s += line + "\n"; 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     System.out.println(s); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
}//end testGetOutput() 

मुझे लगता है कि समस्या यह है कि जब मैं क्वेरी को परिवर्तित करने के लिए एक आदेश जो HandBrakeCLI.exe निष्पादित करेंगे बनने की कोशिश। प्रोग्राम चल रहा है, लेकिन मेरे सिस्टम को देख रहा है (लेकिन ऐसा लगता है), यह मुझे दिखाता है कि HandBrakeCLI.exe एक cmd विंडो के नीचे चल रहा है जो मेरे आईडीई के तहत चलाया जा रहा है। यह सब समझ में आता है, लेकिन HandBrakeCLI.exe बाहर नहीं निकलता है, इसलिए मुझे लगता है कि मैं आउटपुट को अपने प्रोग्राम में इनपुट के रूप में नहीं पढ़ सकता।

तो, उस पृष्ठभूमि के बाद। मेरा बड़ा सवाल यह है: मैं अपनी क्वेरी के साथ समाप्त होने के बाद बंद करने के लिए HandBrakeCLI.exe कैसे प्राप्त करूं ताकि मैं इसका आउटपुट प्राप्त कर सकूं? बस अतिरिक्त जानकारी के लिए, उपरोक्त विधि और स्कैन डीवीडी विधि के बीच एकमात्र अंतर है जो मेरे पास हैंडब्रेकसीआई के लिए है, क्वेरी वैरिएबल अलग है। इस उदाहरण की तरह:

String query = "C:\Users\Kent\Desktop\HBCLI\HandBrakeCLI -t --scan -i "C:\Users\Kent\Desktop\General Conference DVDs\Sources\174th October 2004\DVD 1"; //this is actually a variable in the DVD object, but here's an example' 

ओह, और जिस तरह से, जब मैं एक नियमित रूप से कमांड प्रॉम्प्ट में वह क्वेरी चलाने के लिए, यह वास्तव में करता है मैं यह करने के लिए, मुझे सभी उत्पादन मैं सख्त की इच्छा दे रही है क्या चाहते हैं!

यहाँ मूल समस्या (मुझे यकीन है कि एक सवाल फिर से जमा करने के लिए कैसे नहीं कर रहा हूँ) है:

मैं हर जगह तलाश रहे हैं और इस को समझ नहीं सकता। मुझे यकीन नहीं है कि जो मैंने पाया है वह भी प्रासंगिक है जो मैं करना चाहता हूं। मेरे पास अभी तक बहुत सारे कोड नहीं हैं, इसलिए यह यहां कोड डालने के लिए बहुत कुछ नहीं करेगा और मुझे लगता है कि यह बहुत आसान होना चाहिए, इसलिए मैं यहां कुछ स्क्रीनशॉट देने जा रहा हूं। तो यहाँ मेरी कार्य है:

  1. स्कैन फ़ोल्डर जो फट डीवीडी फ़ोल्डर (VOB फ़ाइलों आदि के साथ video_ts फ़ोल्डर) से भरा हुआ है और डीवीडी के शीर्षक के रूप में इन फ़ोल्डर नाम की दुकान।

  2. हैंडब्रेकसीएलआई का उपयोग करके प्रत्येक फ़ोल्डर को स्कैन करें और आउटपुट को स्ट्रिंग में स्टोर करें।

  3. प्रत्येक शीर्षक, अध्याय और भाषा की पहचान करने के लिए स्ट्रिंग को रीगेक्स करें।

  4. प्रश्नों वापस HandBrakeCLI में भारी मात्रा में एन्कोड करने के लिए प्रत्येक डीवीडी के लिए प्रत्येक शीर्षक में प्रत्येक अध्याय में प्रत्येक भाषा के देने के लिए उत्पन्न (आप देख सकते हैं कारण है कि मैं इस स्वचालित करना चाहते हैं!)

  5. स्टोर एक * में इन प्रश्नों। बल्ले फ़ाइल

एकमात्र भाग जो मुझे यकीन नहीं है चरण 2 है! मैं सबकुछ आसानी से कर सकता हूं। मैंने आउटपुटस्ट्रीम के बारे में बहुत कुछ पढ़ा है, लेकिन मुझे लगता है कि यह कैसे काम करता है यह समझ में नहीं आता है। मुझे वास्तव में आउटपुट को एक स्ट्रिंग में प्राप्त करने की आवश्यकता है जिसे मैं आवश्यक सामग्री प्राप्त करने के लिए regex कर सकता हूं।

इनपुट HandBrakeCLI लिए:

enter image description here

आउटपुट स्कैन करने के लिए: यहाँ मैं क्या मैं इनपुट की जरूरत है और क्या उत्पादन से पट्टी की जरूरत के स्क्रीनशॉट हैं

enter image description here

उत्तर

5

सबसे पहले आप एक गैर अवरुद्ध रास्ते की जरूरत है Standard.out से और Standard.err

private class ProcessResultReader extends Thread 
{ 
    final InputStream is; 
    final String type; 
    final StringBuilder sb; 

    ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type) 
    { 
     this.is = is; 
     this.type = type; 
     this.sb = new StringBuilder(); 
    } 

    public void run() 
    { 
     try 
     { 
      final InputStreamReader isr = new InputStreamReader(is); 
      final BufferedReader br = new BufferedReader(isr); 
      String line = null; 
      while ((line = br.readLine()) != null) 
      { 
       this.sb.append(line).append("\n"); 
      } 
     } 
     catch (final IOException ioe) 
     { 
      System.err.println(ioe.getMessage()); 
      throw new RuntimeException(ioe); 
     } 
    } 

    @Override 
    public String toString() 
    { 
     return this.sb.toString(); 
    } 
} 

तो फिर तुम संबंधित InputStream और OutputStream वस्तुओं में इस वर्ग टाई की जरूरत है पढ़ने के लिए।

try 
    { 
     final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query)); 
     final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR"); 
     final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT"); 
     stderr.start(); 
     stdout.start(); 
     final int exitValue = p.waitFor(); 
     if (exitValue == 0) 
     { 
      System.out.print(stdout.toString()); 
     } 
     else 
     { 
      System.err.print(stderr.toString()); 
     } 
    } 
    catch (final IOException e) 
    { 
     throw new RuntimeException(e); 
    } 
    catch (final InterruptedException e) 
    { 
     throw new RuntimeException(e); 
    } 

यह काफी बॉयलर प्लेट का उपयोग मैं जब मैं जावा में Runtime.exec() कुछ भी करने की जरूरत है।

एक और अधिक उन्नत तरीका सीधे Thread विस्तार जो सबसे अच्छा अभ्यास नहीं है बजाय FutureTask और Callable या कम से कम Runnable उपयोग करने के लिए किया जाएगा।

नोट:

@Nonnull एनोटेशन JSR305 लाइब्रेरी में हैं। यदि आप मेवेन का उपयोग कर रहे हैं, और आप मेवेन का उपयोग कर रहे हैं तो आप नहीं हैं, बस इस निर्भरता को अपने pom.xml पर जोड़ें।

<dependency> 
    <groupId>com.google.code.findbugs</groupId> 
    <artifactId>jsr305</artifactId> 
    <version>1.3.9</version> 
</dependency> 
+0

जारोड, त्वरित प्रतिक्रिया के लिए धन्यवाद! मैं इसे तुरंत लागू करने की कोशिश करूंगा और आपको बताऊंगा कि यह कैसा चल रहा है! – kentcdodds

+0

बिल्कुल सही! मुझे बिल्कुल यकीन नहीं है कि यह कैसे काम करता है। लेकिन मैं इसे समझने के लिए थोड़ा सा देख लूंगा। लेकिन हाँ, यह एक आकर्षण की तरह काम किया! अब मुझे बस उन सभी चीजों को फिर से भरना होगा! वैसे भी, आपकी मदद के लिए एक टन धन्यवाद! ओह, और मुझे यकीन नहीं है कि मेवेन क्या है। मेरा आईडीई नेटबीन है। मुझे सामान जोड़ने की आवश्यकता नहीं थी। एक बार फिर धन्यवाद! आने वाली पीढ़ियों के लिए एक और व्यावहारिक समाधान पोस्ट करने के लिए – kentcdodds

1

मान लें कि आप अपनी बाहरी प्रक्रिया शुरू करने के लिए Runtime.exec() का उपयोग करते हैं, जिससे आपको Process ऑब्जेक्ट दिया जाता है, उस ऑब्जेक्ट पर तीन प्रासंगिक विधियां हैं: getOutputStream(), getInputStream(), और getErrorStream()

मुझे लगता है कि इनके बारे में भ्रमित होना आसान है - आप शायद सोच रहे हैं कि आप प्रक्रिया के आउटपुट को देखना चाहते हैं, इसलिए एक "आउटपुट स्ट्रीम" वह है जो आप चाहते हैं। लेकिन आपको याद रखने की आवश्यकता यह है कि इन ऑब्जेक्ट्स का नाम जावा कोड के परिप्रेक्ष्य से है - एक आउटपुटस्ट्रीम जावा के लिए आउटपुट लिखने के लिए है, जबकि इनपुट इनपुट पढ़ने के लिए जावा के लिए है। जावा की परिप्रेक्ष्य, इनपुट से आपकी बाहरी प्रक्रिया का आउटपुट है।

तो आप getInputStream() का उपयोग करेंगे और आउटपुट पढ़ने के लिए InputStream पर उचित विधियों को कॉल करेंगे। आप यह भी सुनिश्चित करने के लिए getErrorStream() का उपयोग करना चाह सकते हैं कि आप कुछ भी नहीं खो रहे हैं क्योंकि यह मानक त्रुटि के लिए लिखा गया है।

+0

स्पष्टीकरण के लिए धन्यवाद प्राप्त है! वह थोड़ा उलझन में था। अब जिस समस्या का सामना कर रहा हूं वह क्वेरी के परिणामों को प्रिंट करने की बजाय है (जैसा कि मेरे दूसरे स्क्रीनशॉट में देखा गया है), यह क्वेरी को स्वयं प्रिंट कर रहा है। यहां टिप्पणी में जोड़ने के लिए कोड में बहुत अधिक सामग्री है, इसलिए यहां कोलाबैडिट दस्तावेज़ के लिए एक लिंक है: http: // collabedit।कॉम/5r384 – kentcdodds

+0

एक मुद्दा, मुझे लगता है कि, 'exec()' एक वास्तविक निष्पादन योग्य की अपेक्षा करता है - एक बैच फ़ाइल निष्पादन योग्य प्रोग्राम नहीं है, यह विंडोज शैल द्वारा निष्पादित आदेश की एक श्रृंखला है। Http://stackoverflow.com/questions/615948/how-do-i-run-a-batch-file-from-my-java- एप्लिकेशन देखें। –

+0

हम वास्तव में करीब आ रहे हैं! तो अब मेरी समस्या है मेरी buffered पाठक वस्तु शून्य है। मुझे यकीन नहीं है क्यों। मैंने कोलाबैडिट दस्तावेज़ पर कोड अपडेट किया है। आप देखेंगे कि मैंने println को कमांड के आस-पास रखा है क्योंकि कोड कहां है, और कमांडResult.readLine() = null जब इसे पहली इनपुट लाइन के बराबर होना चाहिए (या कम से कम, यही वह है जिसे मैं ढूंढ रहा हूं)। मदद के लिए एक बार फिर से धन्यवाद! http://collabedit.com/5r384 – kentcdodds

5

यह पूर्ण जावा प्रोग्राम उदाहरण कमांड लाइन पर आदेश 'निर्देशिका' (निर्देशिका सूची) चलाता है और एक स्ट्रिंग और यह प्रिंट कंसोल पर में परिणाम खींचती है।

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

public class X { 
    public static void main(String[] args) { 
     try{ 
      String command = "dir"; 
      String s = get_commandline_results(command); 
      System.out.println(s); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
     System.out.println("done"); 
    } 

    public static String get_commandline_results(String cmd) 
     throws IOException, InterruptedException, IllegalCommandException{ 

     //Do not remove the authorizedCommand method. Be prepared 
     //to lose your hard drive if you have not white-listed the 
     //commands that can run. 
     if (!authorizedCommand(cmd)) 
      throw new IllegalCommandException(); 

     String result = ""; 
     final Process p = Runtime.getRuntime(). 
      exec(String.format("cmd /c %s", cmd)); 
     final ProcessResultReader stderr = new ProcessResultReader(
       p.getErrorStream(), "STDERR"); 
     final ProcessResultReader stdout = new ProcessResultReader(
       p.getInputStream(), "STDOUT"); 
     stderr.start(); 
     stdout.start(); 
     final int exitValue = p.waitFor(); 
     if (exitValue == 0){ 
      result = stdout.toString(); 
     } 
     else{ 
      result = stderr.toString(); 
     } 
     return result; 
    } 
    public static boolean authorizedCommand(String cmd){ 
     //Do not allow any command to be run except for the ones 
     //that we have pre-approved here. This lessens the 
     //likelihood that fat fingers will wreck your computer. 
     if (cmd.equals("dir")) 
      return true; 
     //add the commands you want to authorize here. 

     return false; 
    } 
} 

class ProcessResultReader extends Thread{ 
    final InputStream is; 
    final String type; 
    final StringBuilder sb; 

    ProcessResultReader(final InputStream is, String type){ 
     this.is = is; 
     this.type = type; 
     this.sb = new StringBuilder(); 
    } 

    public void run() 
    { 
     try{ 
      final InputStreamReader isr = new InputStreamReader(is); 
      final BufferedReader br = new BufferedReader(isr); 
      String line = null; 
      while ((line = br.readLine()) != null) 
      { 
       this.sb.append(line).append("\n"); 
      } 
     } 
     catch (final IOException ioe) 
     { 
      System.err.println(ioe.getMessage()); 
      throw new RuntimeException(ioe); 
     } 
    } 
    @Override 
    public String toString() 
    { 
     return this.sb.toString(); 
    } 
} 
class IllegalCommandException extends Exception{ 
    private static final long serialVersionUID = 1L; 
    public IllegalCommandException(){ } 
} 

Windows पर, इस परिणाम मैं

Directory of D:\projects\eric\eclipseworkspace\testing2 
07/05/2012 01:06 PM <DIR>   . 
07/05/2012 01:06 PM <DIR>   .. 
06/05/2012 11:11 AM    301 .classpath 
06/05/2012 11:11 AM    384 .project 
06/05/2012 11:11 AM <DIR>   .settings 
07/05/2012 01:42 PM <DIR>   bin 
06/05/2012 11:11 AM <DIR>   src 
07/05/2012 01:06 PM    2,285 usernames.txt 
       3 File(s)   2,970 bytes 
       5 Dir(s) 45,884,035,072 bytes free 

done 
+0

+1। – kentcdodds

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