Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2016.07.24;
Скачать: CL | DM;

Вниз

Копирование потока без хвоста.   Найти похожие ветки 

 
DayGaykin ©   (2015-09-15 22:03) [0]

Простая вводная:
Есть некий поток данных A. Чтение из данных в буфер производится методом A.read(buf, size), который возвращает количество реально прочитанных данных или -1 в случае завершения потока. Длина потока неизвестна до этого момента.
Есть поток B, приемник этих данных. Данные принимаются методом B.write(buf, size). Метод всегда записывает все предоставленные данные.

Теперь усложняем.
Последние 32 байта из потока A не нужно копировать.

Потоки "отматывать" нельзя.

Может где-то есть готовый алгоритм? Я сделал в лоб, но громоздко получилось.

P.S.
Последние 32 байта - контрольная сумма.
По ходу копирования необходимо самостоятельно рассчитать контрольную сумму и сравнить с той, на которую оканчивается потока A.


 
DVM ©   (2015-09-15 22:39) [1]

Есть же size и position в чем сложность не пойму


 
DayGaykin ©   (2015-09-15 22:42) [2]


> DVM ©   (15.09.15 22:39) [1]

Ни А ни B эти свойства не поддерживают.
Сложность не отправить этот хвостик в B.


 
кгшзх ©   (2015-09-15 22:54) [3]

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


 
DayGaykin ©   (2015-09-16 00:26) [4]

Ну то есть в лоб. Примерно так и сделал, только первый буфер большой.

Может кому понадобится (Java):

byte[] tail = new byte[48]; // Буфер хвостика 48 байт.
int tailLength = 0; // Длина полезных данных в буфере хвостика. Данные располагаются у "правого края" буфера.

try (InputStream input = connection.getInputStream()) {
byte[] buffer = new byte[4096];
int read;
while ((read = input.read(buffer)) >= 0) {
 if (read > 0) {
  if (read >= tail.length) {
   if (tailLength > 0) {
    output.write(tail, tail.length - tailLength, tailLength);
    md.update(tail, tail.length - tailLength, tailLength);
   }
   if (read > tail.length) {
    output.write(buffer, 0, read - tail.length);
    md.update(buffer, 0, read - tail.length);
   }
   System.arraycopy(buffer, read - tail.length, tail, 0, tail.length);
   tailLength = tail.length;
  } else {
   if (tailLength + read > tail.length) {
    output.write(tail, tail.length - tailLength, tailLength + read - tail.length);
    md.update(tail, tail.length - tailLength, tailLength + read - tail.length);
    if (tail.length - read > 0) {
     System.arraycopy(tail, read, tail, 0, tail.length - read);
    }
    System.arraycopy(buffer, 0, tail, tail.length - read, read);
    tailLength = tail.length;
   } else {
    if (tailLength > 0) {
     System.arraycopy(tail, tail.length - tailLength, tail, tail.length - tailLength - read, tailLength);
    }
    System.arraycopy(buffer, 0, tail, tail.length - read, read);
    tailLength += read;
   }
  }
 } else {
  Thread.yield();
 }
}
}


 
кгшзх ©   (2015-09-16 00:29) [5]

мда. действительно громоздко.
если банально структурировать код то он похудеет на две трети


 
DayGaykin ©   (2015-09-16 00:35) [6]

Пока довел до "работает без ошибок".
Завтра на свежую голову может и поправлю.

А может и забью, сэкономив оплачиваемое время.


 
ksergey ©   (2015-09-17 09:37) [7]

Если алгоритм вычисления контрольной суммы не слишком затратный (или допустимо затратный) - я бы
1) завёл буфер на 32 байта, где сохранял последние 32 байта, полученные из А
2) тупо переписывал всё из A.read в B.Write (откладывая последние 32 байта, см. пункт 1)
3) постоянно вычислял контрольную сумму на основании прочитанных данных (храня её в отдельном буфере "сумма насчитанная")
4) на момент, когда A.read() вернёт -1 - у меня уже есть
   а) последние 32 байта с контрольной суммой из потока А
   б) готовая насчитанная мною контрольная сумма
Остаётся их только сравнить.

Метод, как я понимаю, не соответствует ТЗ в том, что  я в поток В передам исходную сумму из А (см. пункт 2 "переписывал бы всё тупо полностью"). Хотя и это устранимо, конечно.


 
DayGaykin ©   (2015-09-17 14:25) [8]


> Метод, как я понимаю, не соответствует ТЗ в том, что  я
> в поток В передам исходную сумму из А (см. пункт 2 "переписывал
> бы всё тупо полностью"). Хотя и это устранимо, конечно.

Очень важно этого не делать. Тем не менее алгоритм по сложности сопоставим с требуемым.



Страницы: 1 вся ветка

Текущий архив: 2016.07.24;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.011 c
4-1277230542
Отшельник
2010-06-22 22:15
2016.07.24
Изменить значение в памяти чужой программы которое берется из INI


15-1444929114
ВладОшин
2015-10-15 20:11
2016.07.24
Как то так..


15-1441852590
MonoLife
2015-09-10 05:36
2016.07.24
И почту Yahoo заблокировали


2-1413238792
Германн
2014-10-14 02:19
2016.07.24
Где кликнули правой кнопкой мыши вызывая попап меню?


15-1445622452
Rouse_
2015-10-23 20:47
2016.07.24
Сели тут со знакомым и за два дня ...