2012-04-18 15 views
5

मैं एक जावा प्रोग्राम लिखना चाहता हूं जो बाहरी "जावा myprog < input.txt> output.txt" कमांड चलाता है। अंतिम लक्ष्य इस आदेश को दो अलग-अलग कार्यक्रमों पर चलाने और उनकी आउटपुट समानता की तुलना उनके संबंधित आउटपुट फाइलों से करना है।एक जावा प्रोग्राम जो बाहरी "जावा myprog < input.txt > output.txt" चलाता है

मुझे लगता है कि मैंने बाहरी प्रोग्राम चलाने के लिए प्रोसेसबिल्डर का उपयोग करने के बारे में हर प्रासंगिक लेख और उस बाहरी कार्यक्रम में उपयोगकर्ता इनपुट को संभालने के बारे में कुछ प्रविष्टियां पढ़ी हैं, लेकिन मुझे अभी भी काम नहीं मिल रहा है। मैंने जो पढ़ा है, उससे मुझे लगता है कि सबसे अच्छा तरीका ऊपर दिए गए सटीक कमांड को चलाने के लिए नहीं है, बल्कि इसके बजाय input.txt फ़ाइल को पढ़ें और प्रक्रिया ऑब्जेक्ट में बाइट-बाय-बाइट फ़ीड करें, फिर आउटपुट एकत्र करें और इसे आउटपुट पर लिखें .txt ... मैं अन्य विकल्पों के लिए 100% खुला हूं।

मैंने अपने रीडिंग के आधार पर नीचे दिए गए कोड को एक साथ रखा है। ऐसा लगता है कि input.txt से इनपुट को सही ढंग से फ़ीड करना है, लेकिन जब मैं बाहरी प्रोग्राम के आउटपुट को कंसोल पर प्रिंट करने का प्रयास करता हूं, तो प्रोग्राम उस बिंदु पर लटकता है जहां (आश्चर्य) उपयोगकर्ता इनपुट में मेरी इनपुट की उम्मीद है।

मुझे रीडायरेक्ट एररस्ट्रीम (सत्य) लाइन के साथ और बिना एक ही समस्याएं मिलती हैं।

मैं वास्तव में जावा में होना चाहता हूं क्योंकि मैं स्रोत कोड को उन लोगों के साथ साझा करने की योजना बना रहा हूं जिनके प्रोग्राम आउटपुट की तुलना मैं करूंगा, और वे मुख्य रूप से केवल जावा से परिचित हैं।

import java.io.*; 
import java.util.*; 

public class test7 { 

    public static void main(String args[]) { 

     try { 
      // WANT: "java myprog <input.txt> output.txt" 
      String inputFile = "input.txt"; 
      String outputFile = "output.txt"; 

      ProcessBuilder pb = new ProcessBuilder("java","myprog"); 
      pb.redirectErrorStream(true); // merge stdout, stderr of process 
      Process p = pb.start(); 

      // write input to the running program 
      OutputStream pos = p.getOutputStream(); 
      InputStream fis = new FileInputStream(inputFile); 
      int read = 0; 
      while ((read = fis.read()) != -1) { 
       pos.write(read); 
      } 
      fis.close(); 

      // get output of running program 
      InputStreamReader isr = new InputStreamReader(p.getInputStream()); 
      BufferedReader br = new BufferedReader(isr); 

      // HANGS HERE WHEN USER INPUT REQUIRED 
      String lineRead; 
      while ((lineRead = br.readLine()) != null) { 
       System.out.println(lineRead); 
      } 

     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } // end main 

} 

यहाँ myprog.java की सामग्री है:

import java.io.*; 

public class myprog { 

    public static void main(String args[]) throws IOException { 

     System.out.println("Hello world!"); 
     System.out.println("Enter something:"); 

     BufferedReader cin = new BufferedReader(new InputStreamReader(System.in)); 

     // the readLine() command causes ProcessBuilder to hang 
     cin.readLine(); 
    } 
} 

और input.txt फ़ाइल सिर्फ

p 

output.txt फ़ाइल होना चाहिए है

Hello world! 
Enter something: 
+0

उपयोगकर्ता इनपुट द्वारा आपका क्या मतलब है? क्या आप या तो अपने myprog या कम से कम इसके सबसे प्रासंगिक भागों दिखा सकते हैं? साथ ही, यदि आप बेहतर सहायता चाहते हैं तो कृपया जावा नामकरण सम्मेलनों का पालन करें। गैर मानक नामकरण (कक्षा नामों के पहले अक्षर को कैपिटल करने सहित) का उपयोग आपके कोड को भ्रमित कर देता है। –

+2

मैंने कुछ समय पहले इसका उत्तर दिया .. http://stackoverflow.com/questions/3062305/executing-shell-commands-from-java/3062874#3062874 – dsmith

+0

@ होवरक्राफ्टफुलऑफेल: मैंने myprog.java की सामग्री को विवरण में जोड़ा। कक्षा के नाम को पूंजीकरण के लिए मैं क्षमा चाहता हूं। – missthang

उत्तर

0

क्या आपने Runtime.getRuntime का उपयोग करने के बारे में सोचा है() .exec() इसके बजाय?

Process proc = Runtime.getRuntime().exec("java myprog "+inputFile+" "+outputFile); 
+0

प्रोसेसबिल्डर के उपयोग पर इसका कोई फायदा नहीं है। –

+0

अभी भी वैसे ही लटकता है। – missthang

+0

मैंने अपने उदाहरण में "<" and ">" छोड़ा, क्या आपने इन्हें जोड़ा? @ होवरक्राफ्ट ... कोड बनाम 10 की 1 पंक्ति हमेशा मेरी पुस्तक में एक लाभ है, लेकिन प्रत्येक के लिए। – user282172

0

आप 'myprog' के जार को शामिल कर सकते हैं और मुख्य() विधि स्वयं को कॉल कर सकते हैं। और भी अधिक यदि myprog आपके डोमेन में है तो आप मुख्य विधि से पूरी तरह से छुटकारा पा सकते हैं।

4

मुझे आश्चर्य है कि आपकी समस्या इनपुट और लेखन आउटपुट पढ़ने के लिए अलग-अलग धागे का उपयोग न करने के साथ आंशिक रूप से करने के लिए है। उदाहरण के लिए:

public static void main(String args[]) { 

     try { 
     // WANT: "java myprog <input.txt> output.txt" 
     String inputFile = "input.txt"; 
     String outputFile = "output.txt"; 

     // my ProcessBuilder Strings will be different from yours 
     ProcessBuilder pb = new ProcessBuilder("java", "-cp", ".;bin;", 
       "yr12.m04.a.MyProg"); 
     pb.redirectErrorStream(true); 
     Process p = pb.start(); 

     final OutputStream pos = p.getOutputStream(); 
     final PrintWriter pw = new PrintWriter(pos); 
     final InputStream fis = new FileInputStream(inputFile); 
     final BufferedReader fileBr = new BufferedReader(new InputStreamReader(fis)); 

     InputStreamReader isr = new InputStreamReader(p.getInputStream()); 
     final BufferedReader br = new BufferedReader(isr); 

     new Thread(new Runnable() { 
      public void run() { 
       String lineRead; 
       try { 
        while ((lineRead = br.readLine()) != null) { 
        System.out.println(lineRead); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } finally { 
        if (br != null) { 
        try { 
         br.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        } 
       } 
      } 
     }).start(); 

     new Thread(new Runnable() { 
      public void run() { 
       try { 
        String lineRead; 
        while ((lineRead = fileBr.readLine()) != null) { 
        pw.println(lineRead); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } finally { 
        if (pw != null) { 
        pw.close(); 
        } 
        if (fileBr != null) { 
        try { 
         fileBr.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        } 
       } 
      } 
     }).start(); 

     } catch (IOException e) { 
     e.printStackTrace(); 
     } 
    } // end main 
+0

यही वह है! जावा कमांड से क्लासपाथ स्विच के साथ पूरी तरह से काम करता है। बहुत बहुत धन्यवाद!!!!! – missthang

+0

@ मिस्स्टहांग: खुशी है कि आपको यह काम मिल गया है। –