Как я могу передать ввод в приложение Java с Perl? - PullRequest
1 голос
/ 18 апреля 2010

Мне нужно написать скрипт на Perl, который направляет ввод в программу Java. Это связано с этим , но это мне не помогло. Моя проблема в том, что приложение Java не получает операторы печати, пока я не закрою дескриптор. В Интернете я обнаружил, что $ | необходимо установить значение больше 0, в этом случае символы новой строки будут очищать буфер. Это все еще не работает.

Это скрипт:

#! /usr/bin/perl -w

use strict;
use File::Basename;

$|=1;

open(TP, "| java -jar test.jar") or die "fail";
sleep(2);

print TP "this is test 1\n";
print TP "this is test 2\n";
print "tests printed, waiting 5s\n";
sleep(5);

print "wait over.  closing handle...\n";
close TP;
print "closed.\n";

print "sleeping for 5s...\n";
sleep(5);
print "script finished!\n";
exit

А вот пример приложения Java:

import java.util.Scanner;

public class test{

    public static void main( String[] args ){

        Scanner sc = new Scanner( System.in );
        int crashcount = 0;
        while( true ){
            try{
                String input = sc.nextLine();
                System.out.println( ":: INPUT: " + input );
                if( "bananas".equals(input) ){
                    break;
                }
            } catch( Exception e ){
                System.out.println( ":: EXCEPTION: " + e.toString() );
                crashcount++;
                if( crashcount == 5 ){
                    System.out.println( ":: Looks like stdin is broke" );
                    break;
                }
            }
        }
        System.out.println( ":: IT'S OVER!" );
        return;
    }

}

Приложение Java должно реагировать на получение тестовых отпечатков немедленно, но не до оператора close в скрипте Perl. Что я делаю не так?

Примечание: исправление может быть только в скрипте Perl. Приложение Java не может быть изменено. Также есть File :: Basename, потому что я использую его в реальном скрипте.

Ответы [ 2 ]

3 голосов
/ 18 апреля 2010

Я полюбил производные модули IO::Handle. Они упрощают управление сбросом, чтением данных, двоичным режимом и многими другими аспектами дескриптора.

В этом случае мы используем IO :: File .

use IO::File;

my $tp = IO::File->new( "| java -jar test.jar" )
    or die "fail - $!";

# Manual print and flush
$tp->print( 'I am fond of cake' );
$tp->flush;

# print and flush in one method
$tp->printflush( 'I like pie' );

# Set autoflush ON
$tp->autoflush(1);
$tp->print( 'I still like pie' );

Кроме того, поскольку дескриптор файла имеет лексическую область, вам не нужно закрывать его вручную. Он автоматически закроется, когда выйдет из области видимости.

Кстати, если вы не нацелены на perl старше 5,6, вы можете использовать прагму warnings вместо -w. См. perllexwarn для получения дополнительной информации.

2 голосов
/ 18 апреля 2010

$ | = 1 работает только с текущим выбранным дескриптором файла (по умолчанию STDOUT). Чтобы сделать дескриптор файла TP горячим, вам нужно сделать это после его открытия:

select(TP);
$| = 1;
select(STDOUT);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...