Передача архива через NetworkStream - PullRequest
0 голосов
/ 13 февраля 2012

Я хочу скопировать дерево каталогов через TCP-соединение.Сторона источника должна начинаться где-то в файловой системе, чтобы рекурсивно собирать все файлы и отправлять их на сторону приемника через NetworkStream.Это выглядит как-то так, как я мог бы создать ZIP-файл на стороне источника и отправить его клиенту.Но есть некоторые требования:

  • Не должно быть никаких временных файлов
  • В памяти не должно быть никаких файлов
  • Данные должны бытьотправить в полосе.

Первые два требования могут быть выполнены путем отправки ZIP-архива через NetworkStream.Временных файлов следует избегать из-за проблем с правами доступа.Дерево каталогов может содержать огромное количество данных, что может вызвать проблемы нехватки памяти.Третье требование немного сложнее.Между источником и приемником должно быть установлено только одно TCP-соединение.

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

Я уже пробовал SharpZipLib.Но это читает всегда куски 4 Кбайт при чтении потока.Для определения конца ZIP-архива требуется конец потока.Это неуместно, поскольку архив должен быть внутриполосным.

В документации библиотеки DotNetZip упоминается, что для нее требуется поток для поиска, чего нет у NetworkStream.

Как могут быть такие структуры каталоговпередан?

Редактировать уточнил, что данные файла должны быть встроены в тот же поток TCP.

1 Ответ

0 голосов
/ 14 февраля 2012

Вы правы, что DotNetZip, похоже, не поддерживает потоки без возможности поиска напрямую. Но единственная причина, по которой это требуется, заключается в том, что ему нужно знать Position, который не поддерживаются потоками без поиска.

Чтобы это исправить, просто оберните NetworkStream в CountingStream, предоставляемый как часть DotNetZip. Если вы сделаете это, вы сможете использовать ZipOutputStream очень хорошо.

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

Что-то вроде

  • 4 байта для длины имени файла, включая путь (M)
  • 8 байт для длины файла (N)
  • M байт для имени файла (включая путь), закодированного с использованием UTF-8
  • N байт для содержимого самого файла

для каждого файла.

...