Форум: "Прочее";
Текущий архив: 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.006 c