Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2016.07.24;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.005 c
15-1441149908
Юрий Зотов
2015-09-02 02:25
2016.07.24
Наиважнейшая проблема...


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


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


3-1308474984
Oleg_teacher
2011-06-19 13:16
2016.07.24
Связаные таблицы в БД


15-1442611639
DayGaykin
2015-09-19 00:27
2016.07.24
Помощник игры в Сапера.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский