Главная страница
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.009 c
2-1414065182
Kettle
2014-10-23 15:53
2016.07.24
Присвоение свойству OLE объекта значения NULL


15-1447240616
AndrewAndrey
2015-11-11 14:16
2016.07.24
Права доступа WinServer2012r2


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


2-1414862984
Fox
2014-11-01 20:29
2016.07.24
Вращение карты


15-1444426204
Юрий
2015-10-10 00:30
2016.07.24
С днем рождения ! 10 октября 2015 суббота