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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как перенаправить поток данных, InputStream -> OutputStream 
:(
    Опции темы
Fieral
Дата 27.10.2009, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 1



собсно вопрос:
есть входящий поток данных и исходящий. 
как зарулить входящие данные в исходящие?
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
Kircul
Дата 27.10.2009, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: 6
Всего: 7



Код

InputStream is = ...;
OutputStream os = ...;
byte[] buffer = new byte[BUFFER_SIZE];
for (int bytes; (bytes = is.read(buffer)) != -1;) {
    os.write(buffer, 0, bytes);


Вот так.
PM   Вверх
Fieral
Дата 27.10.2009, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 1



Получается что выполняющий этот код процесс, пока данные не поступают, будет спать внутри метода read ?
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
ivanovpv
Дата 27.10.2009, 15:45 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Варвар
**


Профиль
Группа: Участник
Сообщений: 639
Регистрация: 26.1.2005
Где: Москва

Репутация: 4
Всего: 28



Цитата(Fieral @  27.10.2009,  15:30 Найти цитируемый пост)
Получается что выполняющий этот код процесс, пока данные не поступают, будет спать внутри метода read ?


Да если не засунуть все это хозяйство внутри отдельного потока. Тогда основной поток будет спокойно жить своей жизнью...

Можно использовать available(), чтобы не блокировать read'ом
Код

InputStream is = ...;
OutputStream os = ...;
byte[] buffer = new byte[BUFFER_SIZE];
if(is.available() > 0) {
     for (int bytes; (bytes = is.read(buffer)) != -1;) {
            os.write(buffer, 0, bytes);
     } 
}



--------------------
Aut viam inveniam aut faciam
PM MAIL Skype   Вверх
Fieral
Дата 28.10.2009, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 1



Код

package rebecca.e25.util.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.locks.ReentrantLock;

import rebecca.e25.exe.Lock;
import rebecca.e25.util.HollyShitException;

public class StreamPump implements Runnable {

    
    private InputStream I;
    private OutputStream O;

    public StreamPump(InputStream i, OutputStream o) throws HollyShitException {
        I = i;
        O = o;
        if (I == null) {
            throw new HollyShitException("What`s a hell is that?");
        }
        if (O == null) {
            nullWriteMode = true;
        }

        t = new Thread(this);

        t.start();

    }

    Thread t;
    private boolean nullWriteMode = false;

    public void stopPumping() {

        if (t != null) {
            t.interrupt();
            t = null;
        }
    }

    @Override
    public void run() {
        byte[] buffer = new byte[1024];
        if (!nullWriteMode) {
            try {
                while ((-1 != I.read(buffer))) {
                    O.write(buffer);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else {
            try {
                while ((-1 != I.read(buffer))) {

                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }
}



Хотелось бы услышать критику.
--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
ivanovpv
Дата 28.10.2009, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Варвар
**


Профиль
Группа: Участник
Сообщений: 639
Регистрация: 26.1.2005
Где: Москва

Репутация: 4
Всего: 28



Цитата(Fieral @  28.10.2009,  17:17 Найти цитируемый пост)
Хотелось бы услышать критику. 

1) У вас read() блокирует ваш поток, нужно использовать available() для проверки наличия ввода во входящем потоке
2) Чтобы основной поток дышал нужны вызывать sleep()
3) Метод остановки потока должен быть synchronized, иначе можно нарваться на грубость при работе с потоками

Набросал примерно так:
Код

    public synchronized void stopPumping()
    {
        if (t != null)
        {
            nullWriteMode = true;
        }
    }

    @Override
    public void run()
    {
        int ch=0;
        while (!nullWriteMode)
        {
            Thread.sleep(10);  //даем дышать главному потоку
            if(I.available() > 0)
            {
                for(;;)
                {
                    ch=I.read();
                    if(ch==-1)
                        break;
                    O.write(ch);
                }
            }
        }
    }


Только не забудьте места падения в run() охватить блоками try-catch (сразу весь while)


--------------------
Aut viam inveniam aut faciam
PM MAIL Skype   Вверх
Fieral
Дата 29.10.2009, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 1



Давайте по порядку:

1) read() блокирует Thread t, который я специально для этого и создал (чтоб он там мучился отдельно от основного потока программы).

1.1) Если я буду использовать available(), то когда входящий поток достигнет своего конца, он станет постоянно возвращать (метод available()) ответ 0. И мой поток так и не узнает что там уже "конец". (по этой же причине я и выношу код перенаправления данных в отдельную нить t и юзаю там read(), который при достижении конца выдаст -1)

2) Так как мне может понадобиться отключить "насос" до окончания потока входных данных, то для выполнения отключения я прибиваю t методом t.interrupt();. Таком образом мне удастся "выколупать" спящий  t из метода read() (если вдруг окажется что он там уснул в ожидании входных данных).


--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
ivanovpv
Дата 29.10.2009, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Варвар
**


Профиль
Группа: Участник
Сообщений: 639
Регистрация: 26.1.2005
Где: Москва

Репутация: 4
Всего: 28



Цитата(Fieral @  29.10.2009,  16:19 Найти цитируемый пост)
1) read() блокирует Thread t, который я специально для этого и создал (чтоб он там мучился отдельно от основного потока программы).

Да он там и будет мучиться и одновременно не даст дышать основному потоку, поскольку у него нет sleep'а, чтобы дать дышать основному потоку

Цитата(Fieral @  29.10.2009,  16:19 Найти цитируемый пост)
1.1) Если я буду использовать available(), то когда входящий поток достигнет своего конца, он станет постоянно возвращать (метод available()) ответ 0. И мой поток так и не узнает что там уже "конец". (по этой же причине я и выношу код перенаправления данных в отдельную нить t и юзаю там read(), который при достижении конца выдаст -1)


read() если нет данных блокирует свой поток, раз его блокирует то заблокирует и основной поток (см. выше)


Цитата(Fieral @  29.10.2009,  16:19 Найти цитируемый пост)
2) Так как мне может понадобиться отключить "насос" до окончания потока входных данных, то для выполнения отключения я прибиваю t методом t.interrupt();. Таком образом мне удастся "выколупать" спящий  t из метода read() (если вдруг окажется что он там уснул в ожидании входных данных).

Почти правильно. Но лучше все же останавливать поток штатным средством, а именно устанавливая nullWriteMode в false, в конце концов его проверку можно засунуть в цикл чтения/записи, так что можно будет остановить поток во время чтения/записи, а не после.


--------------------
Aut viam inveniam aut faciam
PM MAIL Skype   Вверх
Fieral
Дата 29.10.2009, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 1



Цитата(ivanovpv @  29.10.2009,  17:53 Найти цитируемый пост)
Почти правильно. Но лучше все же останавливать поток штатным средством, а именно устанавливая nullWriteMode в false, в конце концов его проверку можно засунуть в цикл чтения/записи, так что можно будет остановить поток во время чтения/записи, а не после.

Если поток сидит внутри read() и там ничего не поступает, то он никогда не выйдет наружу что-бы проверить флаг остановки.

Цитата(ivanovpv @  29.10.2009,  17:53 Найти цитируемый пост)
Да он там и будет мучиться и одновременно не даст дышать основному потоку, поскольку у него нет sleep'а, чтобы дать дышать основному потоку

Во время ожидания приостановленный поток не отнимает ресурсы процессора - его усыпляет JVM.

--------------------
Если собака свернулась калачиком, значит будет дождь, а если сидит выпучив глаза, значит у неё запор.
PM MAIL   Вверх
ivanovpv
Дата 29.10.2009, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Варвар
**


Профиль
Группа: Участник
Сообщений: 639
Регистрация: 26.1.2005
Где: Москва

Репутация: 4
Всего: 28



Цитата(Fieral @  29.10.2009,  18:49 Найти цитируемый пост)
Если поток сидит внутри read() и там ничего не поступает, то он никогда не выйдет наружу что-бы проверить флаг остановки.

Именно поэтому и нужен available()  smile 



Это сообщение отредактировал(а) ivanovpv - 29.10.2009, 21:34


--------------------
Aut viam inveniam aut faciam
PM MAIL Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

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

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


 




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


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

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