2012-06-28 19 views
8

पर इनपुटस्ट्रीम पाइप कैसे करें कृपया दूसरे अपडेट पर जाएं। मैं इस प्रश्न के पिछले संदर्भ को बदलना नहीं चाहता था।प्रोसेस बिल्डर

मैं जावा ऐप से wkhtmltoimage का उपयोग कर रहा हूं।

इसका उपयोग करने का मानक तरीका है - path-to-exe http://url.com/ image.png

उनके दस्तावेज़ों के मुताबिक, यदि हम एक इनपुट यूआरएल के बजाय - लिखते हैं, तो इनपुट एसटीडीआईएन में बदल जाता है।

मैं ProcessBuilder का उपयोग कर प्रक्रिया शुरू करने से कर रहा हूँ -

ProcessBuilder pb = new ProcessBuilder(exe_path, " - ", image_save_path); 

Process process = pb.start(); 

अब मैं यह पता लगाने में असमर्थ हूँ कि कैसे इस प्रक्रिया के लिए पाइप एक इनपुट स्ट्रीम करने के लिए।

मैं एक टेम्पलेट फ़ाइल एक DataInputStream में पढ़ा है, और मुझे अंत में एक स्ट्रिंग जोड़कर हूँ: प्रक्रिया के STDIN को

मैं पाइप content
DataInputStream dis = new DataInputStream (new FileInputStream (currentDirectory+"\\bin\\template.txt")); 
byte[] datainBytes = new byte[dis.available()]; 
dis.readFully(datainBytes); 
dis.close(); 

String content = new String(datainBytes, 0, datainBytes.length); 

content+=" <body><div id='chartContainer'><small>Loading chart...</small></div></body></html>"; 

कैसे करूँ?

अद्यतन ---

Andrzej डॉयल द्वारा जवाब के बाद:

मैं का उपयोग किया है की प्रक्रिया के getOutputStream():

ProcessBuilder pb = new ProcessBuilder(full_path, " - ", image_save_path); 

    pb.redirectErrorStream(true); 

    Process process = pb.start();   

    System.out.println("reading"); 

    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); 

    bw.write(content); 

ऐसा करने से यह कहते हुए एक त्रुटि देता है:

Exception in thread "main" java.io.IOException: The pipe has been ended 

2 अद्यतन --------

वर्तमान कोड ब्लॉक में इस तरह के रूप में है:

try { 
     ProcessBuilder pb = new ProcessBuilder(full_path, "--crop-w", width, "--crop-h", height, " - ", image_save_path); 
     System.out.print(full_path+ "--crop-w"+ width+ "--crop-h"+ height+" "+ currentDirectory+"temp.html "+ image_save_path + " "); 
     pb.redirectErrorStream(true); 

     Process process = pb.start(); 
     process.waitFor(); 
     OutputStream stdin = process.getOutputStream(); 

     BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin)); 
// content is the string that I want to write to the process. 

     writer.write(content); 
     writer.newLine(); 
     writer.flush(); 
     writer.close(); 


    } catch (Exception e) { 
     System.out.println("Exception: " + e); 
     e.printStackTrace(); 
    } 

ऊपर कोड चल रहा है मुझे देता है एक IOException: The pipe is being closed.

मैं क्या करने की जरूरत और क्या कर पाइप खोलने के लिए?

+0

आप इस कार्यक्रम के अंत में pb.start कदम नहीं करना चाहिए? (bw.write (सामग्री) के बाद; "हम इसे शुरू करने के बाद किसी प्रक्रिया को कैसे लिखते हैं" पर आधारित एक हंच! – Sap

+0

@Grrrrr मुझे लगता है कि हमें आउटपुटस्ट्रीम प्राप्त करने के लिए एक प्रक्रिया शुरू करने की आवश्यकता होगी। –

+3

आप आउटपुटस्ट्रीम में डेटा लिख ​​रहे हैं, यह अनुवाद करता है कि "आप प्रक्रिया में डेटा लिख ​​रहे हैं!" यदि आप प्रक्रिया का आउटपुट प्राप्त करना चाहते हैं तो आपको प्रक्रिया करना चाहिए .getInputStream और फिर इसे – Sap

उत्तर

3

" - " से सफेद स्थान को निकालना - सामान्य व्हाईटस्पेस को खोल पार्सर द्वारा हटा दिया जाता है, लेकिन यहां ProcessBuilder में, इसका अर्थ (शाब्दिक) फ़ाइल नाम के रूप में शुरू होता है और एक सफेद जगह के साथ समाप्त होता है।

(वास्तव में प्रक्रिया के उत्पादन को देख के रूप में पीटर सुझाव शायद ताकि आप बता दिया होता ...)

3

Process ऑब्जेक्ट बनाने के बाद, आप उस प्रक्रिया को पकड़ने के लिए getOutputStream() पर कॉल कर सकते हैं जो प्रक्रिया को मानक इनपुट में भेजता है।

एक बार जब आप इसे पकड़ लेंगे तो आप जावा के मानक आईओ का उपयोग इस स्ट्रीम को जो भी चाहते हैं उसे लिखने के लिए कर सकते हैं (इसे राइटर में लपेटकर, बफरिंग आदि सहित) - और जैसे ही आप उन्हें लिखेंगे, वे जैसे ही वे फ़्लश हो जाते हैं, प्रक्रिया द्वारा पढ़ा जाए।

+0

मैं 'getOutputStream' का उपयोग कर रहा हूं, और एक बफर से प्रक्रिया को लिख रहा हूं। क्या मैं इसे सही तरीके से कर रहा हूं? मैंने सवाल अपडेट कर लिया है। –

5

क्या कोई कारण है कि आप एक साधारण पाठ फ़ाइल पढ़ने के लिए DataInputStream का उपयोग कर रहे हैं? जावा प्रलेखन

A data input stream lets an application read primitive Java data types from an underlying input stream in a machine-independent way

जिस तरह से आप फ़ाइल पढ़ रहे हैं का कारण बनता है कि एक EOF पाइप से पहले ही अपने स्ट्रिंग के लिए हो जाता है समाप्त करने के लिए पैदा कर रहा outputstream के लिए भेजा जाना यह संभव है से।

आपको आवश्यकताएं फ़ाइल को पढ़ने के लिए बस wkhtmltoimage प्रक्रिया पर जाने से पहले इसे जोड़ने के लिए प्रतीत होती हैं।

आप प्रक्रिया में आउटपुटस्ट्रीम को बंद करने के लिए एक कथन भी खो रहे हैं। यह प्रक्रिया को प्रतीक्षा (लटका) का कारण बन जाएगा जब तक कि यह इनपुट स्ट्रीम से ईओएफ न हो जाए, जो कभी नहीं होगा।

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

ProcessBuilder pb = new ProcessBuilder(full_path, " - ", image_save_path); 
pb.redirectErrorStream(true); 

Process process = null; 
try { 
    process = pb.start(); 
} catch (IOException e) { 
    System.out.println("Couldn't start the process."); 
    e.printStackTrace(); 
} 

System.out.println("reading"); 

try { 
    if (process != null) { 
     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); 

     BufferedReader inputFile = new BufferedReader(new InputStreamReader(new FileInputStream(currentDirectory+"\\bin\\template.txt"))); 

     String currInputLine = null; 
     while((currInputLine = inputFile.readLine()) != null) { 
      bw.write(currInputLine); 
      bw.newLine(); 
     } 
     bw.write("<body><div id='chartContainer'><small>Loading chart...</small></div></body></html>"); 
     bw.newLine(); 
     bw.close(); 
    } 
} catch (IOException e) { 
    System.out.println("Either couldn't read from the template file or couldn't write to the OutputStream."); 
    e.printStackTrace(); 
} 

BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); 

String currLine = null; 
try { 
    while((currLine = br.readLine()) != null) { 
     System.out.println(currLine); 
    } 
} catch (IOException e) { 
    System.out.println("Couldn't read the output."); 
    e.printStackTrace(); 
} 
+0

यह समाधान मेरे मामले के लिए काम किया, इसे पोस्ट करने के लिए धन्यवाद !!! –

6

Exception in thread "main" java.io.IOException: The pipe has been ended

इसका मतलब यह है प्रक्रिया आप शुरू कर दिया है मर गया है। मेरा सुझाव है कि आप आउटपुट को क्यों देखें। जैसे क्या यह आपको एक त्रुटि देता है।

+0

प्रक्रिया की त्रुटि धारा ने वही बात कहा - "पाइप समाप्त हो गया है"। –

+0

मैंने 'waitFor' कमांड भी जोड़ा है: 'process.waitFor();' –

+0

मैंने कभी ऐसा प्रोग्राम नहीं देखा है जो कमांड लाइन से चलने पर ऐसी त्रुटि देता है। –

1

निम्न कोड के रूप में अच्छी तरह से काम करता है:

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

public class ProcessTest { 

    public static void main(String[] args) throws Exception { 
     ProcessBuilder pb = new ProcessBuilder("/home/me/stdinecho"); 
     pb.redirectOutput(ProcessBuilder.Redirect.INHERIT); 
     Process proc = pb.start(); 

     // Input file 
     DataInputStream din = new DataInputStream((new FileInputStream("/home/me/stdinecho.cp"))); 
     byte[] dinBytes = new byte[din.available()]; 
     din.readFully(dinBytes); 
     din.close(); 
     String content = new String(dinBytes, 0, dinBytes.length); 
     content = "header\n" + content + "\nfooter"; 

     BufferedInputStream procStdout = new BufferedInputStream(proc.getInputStream()); 
     OutputStream stdin = proc.getOutputStream(); 

     stdin.write(content.getBytes()); 
     stdin.flush(); 
    } 

} 

यहाँ stdinecho.cpp कार्यक्रम है कि रेखा अपनी शीघ्र पर दर्ज किया गया आउटपुट है:

#include <iostream> 
#include <fstream> 
#include <cstdio> 

using namespace std; 

int main() 
{ 
    string strOutput; 
    string str; 
    while(getline(cin, str)) { 
     cout << str << endl; 
    } 
} 
संबंधित मुद्दे