Главная страница
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.014 c
15-1447765802
Кто б сомневался
2015-11-17 16:10
2016.07.24
Digital signatures - как узнать name of signer программно


15-1447832032
Dimka Maslov
2015-11-18 10:33
2016.07.24
Вот интересно


2-1416114619
topdon
2014-11-16 08:10
2016.07.24
Компонент "Страница HTML" Delphi XE7


2-1415425555
Signal
2014-11-08 08:45
2016.07.24
Чтение почты через протокол с TLS порт 995


15-1445464093
Kerk
2015-10-22 00:48
2016.07.24
CSS