Случайные ошибки jsch при использовании нескольких объектов OutputStream, созданных из одного объекта ChannelSftp.JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Случайные ошибки jsch при использовании нескольких объектов OutputStream, созданных из одного объекта ChannelSftp.

Сообщение Anonymous »

В моем приложении мне приходится одновременно записывать несколько файлов на удаленный сервер. «одновременно» не означает «одновременно», мне просто нужно иметь несколько открытых выходных потоков.
Я начинаю с создания сеанса jsch, затем открываю ChannelSftp и подключитесь к нему. Затем начинается основной цикл приложения, в котором я
  • создаю объекты OutputStream из объекта ChannelSftp с помощью put()
  • время от времени записывайте данные в объекты OutputStream с помощью write()
  • закрывайте объекты OutputStream когда они больше не нужны, используйтеlush(), а затем close()
Для ясности:
  • эти действия зависят от обрабатываемых данных, поэтому иногда может быть открыто более одного объекта OutputStream. в одно и то же время (что-то вроде открыть первую ОС, записать в нее, открыть вторую ОС, записать в нее, снова записать в первую, открыть третью ОС, записать в нее, снова записать во вторую, закрыть вторую, снова записать в первую и и так далее).
  • Я не нарушаю принцип открытия-записи-закрытия последовательность для какой-либо конкретной ОС, т.е. не пытаться писать в закрытую или еще не открытую ОС, закрывать уже закрытую ОС и т. д.
  • Я не пытаюсь открыть более одной ОС для каждого файла или открыть ОС для файла со слишком длинным именем или именем, содержащим недопустимые символы или что-то в этом роде.
Проблема в том, что я получаю ошибки jsch при записи в существующую ОС, открытие новой или закрытие уже существующей. Вот несколько минимальных примеров:
  • Предварительное открытие нескольких ОС работает:

Код: Выделить всё

OutputStream os1 = sftpChannel.put("file1");
OutputStream os2 = sftpChannel.put("file2");
os1.write("1".getBytes());
os2.write("2".getBytes());
os1.flush(); os1.close();
os2.flush(); os2.close();
  • Открытие одной ОС, запись в нее и последующая попытка открыть другую ОС приводит к возникновению исключения SftpException с кодом 4 и без описания

    Код: Выделить всё

    OutputStream os1 = sftpChannel.put("file1");
    os1.write("1".getBytes());
    OutputStream os2 = sftpChannel.put("file2"); // SftpException 4:
    os2.write("2".getBytes());
    os1.flush(); os1.close();
    os2.flush(); os2.close();
    
  • Открытие одной ОС, запись в нее более одного раза, а затем попытка открыть другую ОС приводит к возникновению исключения SftpException с кодом 0 и описанием «Успех».

Код: Выделить всё

OutputStream os1 = sftpChannel.put("file1");
os1.write("1".getBytes());
os1.write("1".getBytes());
OutputStream os2 = sftpChannel.put("file2"); // SftpException 0: Success
os2.write("2".getBytes());
os1.flush(); os1.close();
os2.flush(); os2.close();
  • Можно открыть новую ОС после записи в другую ОС, если существующие были сброшены ранее

    Код: Выделить всё

    OutputStream os1 = sftpChannel.put("file1");
    OutputStream os2 = sftpChannel.put("file2");
    os1.write("1".getBytes());
    os2.write("2".getBytes());
    os1.flush();
    os2.flush();
    OutputStream os3 = sftpChannel.put("file3"); // no exception
    os3.write("3".getBytes());
    os1.flush(); os1.close();
    os2.flush(); os2.close();
    os3.flush(); os3.close();
    
  • Открытие двух ОС, запись в одну несколько раз, а затем попытка записи в другую МОЖЕТ привести к возникновению исключения IOException с кодом 4 и без описания.

Код: Выделить всё

OutputStream os1 = sftpChannel.put("file1");
OutputStream os2 = sftpChannel.put("file2");
os1.write("1".getBytes());
os1.write("1".getBytes());
os1.write("1".getBytes());
os1.write("1".getBytes());
os1.write("1".getBytes());
os1.write("1".getBytes());
os1.write("1".getBytes());
os1.write("1".getBytes());
os1.write("1".getBytes());
os1.write("1".getBytes());
os2.write("2".getBytes()); // IOException 4:
os1.flush(); os1.close();
os2.flush(); os2.close();
Это поведение зависит от количества вызовов write(). В моем случае вызовы write() 5/10/15 приводили к исключению примерно в 0%/50%/100% случаев выполнения примера кода соответственно. Очевидно, это не имеет никакого отношения к общему объему отправленных данных (т.е. 20 вызовов write(), объединенных в один, не создают вышеупомянутое исключение). Этого исключения также можно избежать, очистив первую ОС перед попыткой записи во вторую.
Все примеры подразумевают, что sftpChannel является допустимым экземпляром ChannelSftp. с вызовом Connect() и текущим удаленным каталогом, установленным в существующий каталог, имеющий все необходимые разрешения.
У меня есть как минимум два возможные решения проблемы (всегда прошивать каждую ОС после записи к нему или создать отдельный канал для каждого файла), однако я все еще хочу знать, что вызывает эти проблемы, поскольку в документации jsch ничего не говорится о том, почему несколько ОС, созданные с использованием одного и того же объекта ChannelSftp, могут мешать друг другу .

Подробнее здесь: https://stackoverflow.com/questions/793 ... rom-single
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»