Превышен лимит размера BufferedReader?

В веб-приложении java 6 я пытаюсь получить большой объем вывода из выполненной команды. Я "позаимствовал/украл/основан" на статья javaworld. Проблема, с которой я столкнулся, заключается в том, что длина превышает предельный размер, поскольку вывод обрезается. Я вывел данные в файл, поэтому я могу видеть размер того, что возвращается, и это ровно 32 КБ (32768). Я экспериментировал с изменением размера буфера по умолчанию (см. конструктор BufferedReader), но я не заметил никаких изменений в длине возвращаемых данных, независимо от того, какое значение у меня есть для размера буфера (от очень маленького до очень большого) .

Любой совет будет очень признателен!

public class StreamGobbler extends Thread {

private InputStream is;
private String type;
private List<String> output;

public StreamGobbler(InputStream is, String type) {
    this.is = is;
    this.type = type;
}

@Override
public void run() {
    try {
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line = null;
        this.output = new ArrayList<String>();
        while ((line = br.readLine()) != null) {
            this.getOutput().add(line + "\n");
            System.out.println(type + ">" + line);
        }
        br.close();
    } catch (IOException ioe) {
        System.err.println("ERROR: " + ioe.getMessage());
    }
}

/**
 * @return the output
 */
public List<String> getOutput() {
    return output;
}

}

public class JobClassAds {

private String CONDOR_HISTORY = "condor_history";
private String CONDOR_HISTORY_XML = CONDOR_HISTORY + " -xml";
private String CONDOR_HISTORY_LONG = CONDOR_HISTORY + " -long";

public String getHistory() {
    try {
        Runtime runtime = Runtime.getRuntime();
        String exec = CONDOR_HISTORY_LONG;
        Process process = runtime.exec(exec);
        System.out.println("Running " + exec + " ...");

        // Error message
        StreamGobbler errGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");

        // Output
        StreamGobbler outGobbler = new StreamGobbler(process.getInputStream(), "OUTPUT");

        Thread outThread = new Thread(outGobbler);
        Thread errThread = new Thread(errGobbler);

        outThread.start();
        errThread.start();

        outThread.join();
        errThread.join();

        /*
        String line = null;

        while ((line = input.readLine()) != null) {
            System.out.println(line);
            content.append(line);
        }

         *
         */

        int exitVal = process.waitFor();

        List<String> output = outGobbler.getOutput();
        String inputString = "";
        for (String o : output) {
            inputString += o;
        }

        System.out.println(exec + " Exited with error code " + exitVal);

        BufferedWriter out = new BufferedWriter(new FileWriter("/tmp/history_result.xml"));
        out.write(inputString);
        out.close();
        return inputString;

    } catch (Exception e) {
        System.err.println(e.getMessage());
        return null;
    }
}

person samiam    schedule 15.11.2010    source источник
comment
Изменение размера буфера в BufferedReader просто изменит объем временного хранилища, которое он использует внутри. BufferedReader не имеет ограничений по размеру, поэтому вы сможете прочитать весь вывод с помощью этого кода. Вы проверили, что сам condor_history -long выдает полный вывод и не останавливается на 32 КБ?   -  person Zarkonnen    schedule 16.11.2010
comment
Спасибо за уточнение. Выполнение команды возвращает полный вывод.   -  person samiam    schedule 16.11.2010


Ответы (1)


Проблема не в размере буфера BufferedReader.

Я думаю, что настоящая причина - это то, что делает внешняя команда. Я подозреваю, что он выручает, не очищая поток stdout. Обратите внимание, что вы «пожираете», но не выводите поток stderr команды. Вот где вы можете найти доказательства, указывающие на реальную причину проблемы.


Кстати, вы используете класс StreamGobbler неоптимальным образом. Он расширяет Thread, поэтому предполагаемый способ использования:

    SteamGobbler sg = new StreamGobbler(...);
    sg.start();
    sg.join();

но вы эффективно делаете это:

    SteamGobbler sg = new StreamGobbler(...);
    Thread th = new Thread(sg);
    th.start();
    th.join();

Это работает... но только потому, что Thread является Runnable.

person Stephen C    schedule 15.11.2010
comment
Спасибо. Запуск cli возвращает полный вывод. Благодарим за обратную связь в теме. Так было у меня изначально, поэтому я вернул его. - person samiam; 16.11.2010
comment
@samiam - Запуск cli возвращает полный вывод.. Это не означает, что это не вина внешней команды. Аргументы командной строки или переменные среды могут отличаться и т. д. Вам необходимо проверить содержимое stderr. - person Stephen C; 17.11.2010