By default, WCF uses the cache transmission mode, but this will occupy valuable memory resources of the server. The more connections there are, the more memory occupied. When big data, especially large files, is transmitted, memory will consume light. Some people have provided a big data transmission solution in WCF, but it is still in cache mode, which is inconvenient to manage and cannot be used.
Obviously, using the stream transmission mode can solve the above problems. However, the stream is also inconvenient. First, it does not support sessions. It can only work in percall mode. User authentication information cannot be stored on the server through sessions, however, you can use the message header to send verification messages. Second, certificates are not supported. However, in this regard, stream transmission does not require certificate encryption, the stream itself is transmitted, not the complete content, so even if it is intercepted, it cannot be interpreted.
The default stream transmission has a disadvantage. You cannot specify the stream offset and length for transmission. It always transmits all streams. When the server reads the stream to its end position, the transmission ends. However, we only need to transform the stream to be transmitted to achieve the desired effect. The following shows the starting position of the transmission and the number of bytes in the file stream transmission. Client calls are not listed, and there are a lot of uses. For example, you can use it to implement resumable data transfer. The amount of data transferred during transmission is recorded. Once the stream transmission is interrupted, the next time you re-transmit the data, you only need to re-transmit the data from the recorded transfer volume location. It can also be used as a multi-thread transmission method. After the file is segmented manually, multiple clients are enabled to connect to the file for transmission.
KeyCodeAs follows:
[Servicecontract]
Public Interface IServer: idisposable
{
[Operationcontract]
Stream downloadfilestream ( String Path, Long Offset, Long Count );
}
Custom file stream
Public Class Cusfilestream: filestream
{
Long _ Count;
Long _ Lastposition;
Public Cusstream (intptr handle, fileaccess)
: Base (Handle, access ){}
Public Cusstream ( String Path, filemode mode, fileaccess access, fileshare share)
: Base (Path, mode, access ){}
Public Cusstream ( String Path, filemode mode, fileaccess access, fileshare share, Long Offset, Long Count)
: Base (Path, mode, access)
{
Base . Position = Offset;
_ Count = Count;
_ Lastposition = Offset + Count;
}
PublicCusstream (StringPath, filemode mode, fileaccess access, fileshare share,IntBuffersize)
:Base(Path, mode, access, share, buffersize ){}
Public Override Int Read ( Byte [] Array, Int Offset, Int Count)
{
If ( This . _ Count > 0 && Position + Count > This . _ Lastposition)
Return Base . Read (array, offset ,( Int )( This . _ Lastposition - Position ));
Else
Return Base . Read (array, offset, count );
}
Public Override Int Readbyte ()
{
If ( This . _ Count > 0 && Position > = This . _ Lastposition)
Return - 1 ;
Else
Return Base . Readbyte ();
}
}
Service
[Servicebehavior]
Public Class Server: iServer
{
Public Stream downloadfilestream ( String Path, Long Offset, Long Count)
{
Cusstream FS = New Cusstream (path, filemode. Open, fileaccess. Read, fileshare. Read, offset, count );
Return FS;
}
}