Непълни данни от поток

Чета данни от процесен поток. По принцип изпълнявам процеса с помощта на API на Runtime.exec и получавам входния поток на процеса.

Runtime rt = Runtime.getRuntime();
process = rt.exec("C:/cygwin/home/grec.exe");
InputStream is = process.getInputStream();

След това събирам резултата от процеса като --

            BufferedReader in = new BufferedReader(is);         
            char[] ls = new char[s.available()];
            ls.read(ls);
            String output = new String(ls);

Въпреки това, когато отпечатвам изходния низ, получавам --

  break [loc]     Add a breakpoint at [file:]line or template
  callflow [val]  Enable call flow tracing
  next            Execute the over instruction, stepping over calls
  over            Execute the current instruction hierarchy

Но действителният резултат е...

  break [loc]     Add a breakpoint at [file:]line or template
  callflow [val]  Enable call flow tracing 
  next            Execute the over instruction, stepping over calls
  over            Execute the current instruction hierarchy
  print <xpath>   Print the value of an XPath expression
 profile [val]   Turn profiler on or off
 reload          Reload the script contents
 run             Restart the script
 step            Execute the next instruction, stepping into calls
 verbose         Turn on verbose (-v) output logging
 where           Show the backtrace of template calls
 quit            Quit debugger

Тоест, част от изхода се съкращава, но не се хвърля изключение от кода. Опитах да увелича размера на BufferedReader и също така да увелича размера на масива ls. Затруднявам се да намеря причината за това поведение. Всякакви съвети или насоки за това каква може да е причината за това ще бъдат високо оценени.


person user496934    schedule 16.01.2012    source източник
comment
Какво е s във вашия примерен код? И може би съм пропуснал нещо, но какво ще кажете за: OutputStream out = process.getOutputStream(); BufferedReader bufferedOut = new BufferedReader(out);   -  person bpgergo    schedule 16.01.2012
comment
Всъщност правя абсолютно същото. И това е, което правя...   -  person user496934    schedule 16.01.2012
comment
Тук всъщност s означава InputStream. Това е --InputStream s = process.getInputStream();   -  person user496934    schedule 16.01.2012
comment
Защо не използвате in.readline()? Защо създавате char масив?   -  person artbristol    schedule 16.01.2012


Отговори (2)


Използвайте цикъл, за да обработите цялата информация и да прочетете до края на потока.

Inputstream.available() не прави това, което очаквахте:

Връща оценка на броя байтове, които могат да бъдат прочетени (или прескочени) от този входен поток без блокиране от следващото извикване на метод за този входен поток.

http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available%28%29

person Ishtar    schedule 16.01.2012

Правите грешка, като приемате, че available() ви казва колко байта / знака са действително налични. Всъщност то ви казва, че поне толкова са налични ... и може да е грешно, защото е приблизителна оценка.

Тогава вие усложнявате проблема, като осъществявате достъп до InputStream, след като сте го увили в BufferedReader. Така че вместо да получите броя на знаците, които могат да бъдат прочетени от четеца, вие получавате броя на наличните байтове, които все още не са прочетени в буфера.


Вероятно е по-добре просто да четете от BufferedReader ред по ред, като използвате readLine().

person Stephen C    schedule 16.01.2012
comment
Здравей Стивън, Благодаря за пояснението. Сега разбирам грешката в моя код. Опитах да използвам BufferedReader.readLine API в моя код. Тук обаче се сблъсквам с друг проблем. Моят изход от процеса е -- sdb: SLAX Debugger (версия 0.9.6) Въведете 'help' за помощ (sdb) - person user496934; 16.01.2012
comment
Последният ред е ‹sdb›. В този случай извикването readLine просто увисва, без да дава изключение. - person user496934; 16.01.2012
comment
Изходът на процеса винаги съдържа ‹sdb› като окончателен putput. Той получава всички редове правилно, но винаги виси на последния ред и не се връща от последното извикване на readLine. - person user496934; 16.01.2012
comment
Причината е, че последният ред няма нов ред (все още). Ако искате да можете да се справите с това, ще трябва да използвате символ по един и да се справяте с подканата по подходящ начин. - person Stephen C; 16.01.2012
comment
Благодаря за вашия принос..наистина оценявам. Но можете ли да обясните това малко по-подробно, с код. Как да се справя с последния ред, без да накарам readLine да увисне. Освен това процесът може да варира по отношение на броя на редовете.. така че как да се справя с това по общ начин-- - person user496934; 16.01.2012
comment
Използвам този код--BufferedReader в = нов BufferedReader(isr); while ((line = in.readLine()) != null) { System.out.println(Прокарайте този +line); изход=изход+\n+ред; //System.out.println(in.ready()); } - person user496934; 16.01.2012
comment
@user496934 - ако трябва да се справите с частични линии, не можете да използвате readLine(). Трябва да четете (и обработвате) един знак наведнъж, като използвате read(). - person Stephen C; 16.01.2012
comment
Благодаря, Стивън. Наистина оценявам помощта ви в това. И сега успях да преодолея този проблем, като направих някои промени в кода. Но сега съм изправен пред друг проблем. При еднократен сценарий процесът излъчва някакъв xml като изведен като -- - person user496934; 16.01.2012
comment
‹?xml версия=1.0?› Източник‹junos-output› сигурност { zones { security-zone адрес } } ‹/junos-output›‹local-variabl $destAdd = ; $addName = ; $ipAdd = 172.168.1.2; $serviceN = junos-ftp; $zone = Доверие; $destAddress = защитена_зона; $permit = разрешение; $src = източник; $count = брой; $log = сесия-init; $val = ; ‹/local-variables› Скриптът излезе нормално. (sdb) - person user496934; 16.01.2012
comment
В този случай виждам, че readLine не може да получи никакви изходни данни... всъщност първото извикване на readLine просто виси за неопределено време. - person user496934; 16.01.2012