Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поток виснет 
:(
    Опции темы
simanyay
Дата 16.7.2005, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Антон Ковалёв
****


Профиль
Группа: Участник
Сообщений: 2053
Регистрация: 22.8.2002

Репутация: 3
Всего: 36



Помнится, когда-то я уже боролся с проблемой зависания потока вызова внешней программы (javac). Так вот то решение (JAVA-JAV-002924) прекрасно работает с компилятором, но когда я пытаюсь вызвать другую программу, а в моём случае это mysqldump, поток опять виснет smile Самое интересное, что при пошаговом прохождении кода, всё работает. Ну и, как говорится, пожалуйста, помогите.

Executer.java (хотя в статье фака он есть)
Код

package org.simanyay.jizer.kernel;

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

/**
 * Executes external program 
 * 
 * @author simanyay
 * @see http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps_p.html
 */
class Executer {
    private List<String> err_output; // Error output
    private List<String> nor_output; // Normal output
    private StringBuffer console_output;
    private int exit_value;
    
    private final int ARRAY = 1;
    private final int STRING = 2;
    
    public void execute(String cmd) throws Exception {
        genericExec(cmd, STRING);
    }
    
    public void execute(String[] cmd) throws Exception {
        genericExec(cmd, ARRAY);
    }
    
    private void genericExec(Object cmd, int type) throws Exception {
        Runtime runtime = Runtime.getRuntime();
        Process proc = null;
        
        if(type == STRING) {
            proc = runtime.exec((String) cmd);
        } else if(type == ARRAY) {
            proc = runtime.exec((String[]) cmd);
        } else throw new IllegalArgumentException();
        
        Streamer err_stream = new Streamer(proc.getErrorStream());
        Streamer out_stream = new Streamer(proc.getInputStream());
        
        err_stream.run();
        out_stream.run();
        
        exit_value = proc.waitFor();
        
        console_output = new StringBuffer();
        
        for(String s : err_stream.getOutput()) {
            console_output.append(s + "\n");
        }
        
        for(String s : out_stream.getOutput()) {
            console_output.append(s + "\n");
        }
    }

    public int getExitValue() {
        return exit_value;
    }

    public StringBuffer getConsoleOutput() {
        return console_output;
    }
}

/**
 * Every stream (stdin or stderr) should have it's own thread because some native platforms
 * provide limited buffer size for input and output streams, so failure to promptly write the
 * input stream or read the output stream of the subproccess may cause the subproccess to block,
 * and even deadlock.
 * 
 * @author simanyay
 */
class Streamer extends Thread {
    private InputStream input;
    private List<String> output;

    public Streamer(InputStream in) {
        input = in;
        output = new ArrayList<String>();
    }

    public List<String> getOutput() {
        return output;
    }
    
    public void run() {
        output.clear();
        
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            String line = null;
            if(!reader.ready()) return;
            while((line = reader.readLine()) != null) {
                output.add(line);
            }
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}



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

Код

public boolean exportState(String state) {
    try {
        String cmd = "mysqldump -X demo -u root --password=\"somepassword\"";
            
        Executer console = new Executer();
        
        console.execute(cmd);
        System.out.println(console.getConsoleOutput());
        
        if(console.getExitValue() == 0) return true;
        else return false;
    } catch(Exception e) {
        e.printStackTrace();
        return false;
    }
}



--------------------
«It's better to be a pirate than to join the Navy» — Steve Jobs.
PM MAIL WWW   Вверх
tux
Дата 17.7.2005, 08:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 31
Всего: 132



Проблема здесь:
Код

if (!reader.ready()) return;

Mysqldump нужно определенное время на формирование вывода и при первом вызове reader.ready() читать еще нечего, а вызов этот неблокирующий. reader.readLine() же видимо блокирует поток до тех пор, пока не поступят данные (или поток не закроется). А в остальном все работает как часы smile

Это сообщение отредактировал(а) tux - 17.7.2005, 08:14
PM MAIL Skype GTalk Jabber YIM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0426 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.