I want to copy a directory tree through a TCP connection. The source side should start somewhere in the filesystem to gather all files recursively and send them to the sink side through a NetworkStream. This looks somehow as I could create a ZIP file at source side and send it to the client. But there are some requirements:
The first two requirements could be fulfilled by sending a ZIP archive through the NetworkStream. The temporary files should be avoided due to access right issues. The directory tree can contain huge amount of data what can cause out-of-memory issues. The third requirement is a bit more complicated. There should be established only one TCP connection between source and sink.
The protocol uses the same connection before the data transmission for exchange of meta information like the directory name and after the data transmission to at least acknowledge the successfull transfer and that the data has been written to the file system.
I already tried SharpZipLib. But this reads always chunks of 4 KByte when reading a stream. It needs an end of stream to identify the end of the ZIP archive. This is inappropriate since the archive should be in-band.
The DotNetZip library documentation mentions that it needs a seekable stream, what is not available for a NetworkStream.
How can such directory structures be transferred?
Edit clarified that the file data must be embedded in the same TCP stream.
You are right that DotNetZip doesn't seem to support non-seekable streams directly. But the only reason why it requires that is because it needs to know the Position
, which non-seekable streams don't support.
To fix that, just wrap the NetworkStream
in a CountingStream
, provided as a part of DotNetZip. If you do that, you should be able to use ZipOutputStream
just fine.
As an alternative, if you don't need compression, you could create your own tar-like protocol.
Something like
fore each file.