2012-06-28 22 views
8

Lütfen 2. güncelleştirmeye aşağı doğru hareket edin. Bu sorunun önceki bağlamını değiştirmek istemedim.InputStream, ProcessBuilder ürününe nasıl yollanır

Bir Java uygulamasından wkhtmltoimage kullanıyorum.

Kullanmanın standart yolu - path-to-exe http://url.com/ image.png.

Dokümanlarına göre, bir giriş URL'si yerine - yazarsak, giriş STDIN'e geçer.

Ben ProcessBuilder kullanarak işlemi başlıyorum -

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

Process process = pb.start(); 

Şimdi anlamaya edemiyorum nasıl bu sürece boru bir giriş akışı için.

Ben DataInputStream içine oku şablon dosyası var ve ben sonunda bir dize ekleyerek ediyorum:

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>"; 

nasıl pipomu content sürecin STDIN için?

ben kullandım sürecin getOutputStream(): Andrzej Doyle tarafından cevap takiben

GÜNCELLEME ---

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); 

Aksi belirten bir hata veriyor:

2 GÜNCELLEME --------

geçerli kod bloğu gibi geçerli:

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(); 
    } 

yukarıdaki kodu Koşu bana veren IOException: The pipe is being closed. yapmam gereken başka ne

boruyu açık tutmak için?

+0

Eğer program sonunda pb.start hareket olmamalı (Peter muhtemelen bu yüzden size söylerdim önerildiği gibi Aslında ... sürecin çıkışında bakarak)? (bw.write (content) 'dan sonra, sadece bir önsezi "başladıktan sonra bir işleme nasıl yazabiliriz?" e dayanıyor. – Sap

+0

@Grrrrr Bence çıkış akışını elde etmek için bir işlem başlatmamız gerekecek. –

+3

Çıktı akışına veri yazıyorsunuz, "işleminiz için veri yazıyorsunuz!" Eğer işlemin çıktısını almak istiyorsanız, o zaman process.getInputStream yapmalı ve sonra bunu okuyalım – Sap

cevap

3

" - " gelen boşluk çıkarın - Normal whitespaces kabuk ayrıştırıcı tarafından kaldırılır, ancak burada ProcessBuilder'da, bir boşluk ile başlayan ve biten (literal) dosya adı olarak yorumlanır.

3

Process nesnesini oluşturduktan sonra, içeriğini 'standart giriş işlemine gönderen bir akışa sahip olmak için getOutputStream() numaralı telefonu arayabilirsiniz.

Bunu bir kez tuttuktan sonra, istediğiniz akışa (Yazarda sarma, arabellek ekleme, vb. Dahil) herhangi bir baytı yazmak için Java'nın standart IO'sunu kullanabilirsiniz. İşlemden geçirildikleri anda işlem tarafından okunmalıdır.

+0

"getOutputStream" öğesini kullanıyorum ve bir arabellek işlemine yazıyorum. Doğru mu yapıyorum? Soruyu güncelledim. –

5

Basit bir metin dosyasını okumak için DataInputStream kullanmanın bir nedeni var mı? Java belgelerine

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

dosyayı okuduğunuz yolu bir EOF sizin dizeye ulaşmadan sona boru neden OutputStream gönderilmesine neden olduğunu Mümkün itibaren.

Gereksinimleriniz wkhtmltoimage işlemine geçmeden önce ona eklemek için dosyayı okumak gibi görünüyor.

Ayrıca, çıktı akışını sürece kapatmak için bir deyimi de kaçırıyorsunuz. Bu, işlemin hiçbir zaman olmayacak şekilde giriş akışından bir EOF alana kadar beklemesine (askıda kalmasına) neden olur.

Bunun yerine bir BufferedReader kullanmanız ve ek dizginizi eklemeden önce doğrudan çıktı akışına yazmanızı öneririz. Ardından akışı kapatmak için close() öğesini çağırın.

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

Bu çözüm benim durumum için çalıştı, yayın için teşekkürler !!! –

6

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

Bu başladık süreç öldü demektir. Nedenini görmek için çıktıyı okumanı tavsiye ederim. Örneğin. Size bir hata verdi.

+0

İşlemin hata akışı aynı şeyi söyledi - "Boru bitti". –

+0

Ayrıca bir 'waitFor' komutu ekledim:' process.waitFor(); ' –

+0

Komut satırından çalıştırıldığında böyle bir hata veren bir program görmedim. –

1

Aşağıdaki kod yanı çalışır: Burada

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 kendi istemine girilen satır sonucu programdır:

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

using namespace std; 

int main() 
{ 
    string strOutput; 
    string str; 
    while(getline(cin, str)) { 
     cout << str << endl; 
    } 
}