Я создаю решение, в котором служба WCF выступает в качестве шлюза между FTP-сервером, к которому он должен получить удаленный доступ по протоколу FTP (сервер Linux), и клиентским приложением Windows. Сам сервис будет размещен на сервере Windows IIS.
Я основал свою модель на статье о потоковой передаче файлов через http с использованием WCF, но проблема заключается в следующем:
Мне нужно сначала дождаться загрузки файла на сервер Windows, прежде чем отправить его клиенту, и это может стать серьезной проблемой производительности. Я хочу направить потоковые файлы с FTP-сервера на клиент без необходимости сначала загружать его.
вот код ..
public class TransferService : ITransferService{
Starksoft.Net.Ftp.FtpClient ftp = new Starksoft.Net.Ftp.FtpClient();
public RemoteFileInfo DownloadFile(DownloadRequest request)
{
RemoteFileInfo result = new RemoteFileInfo();
try
{
string filePath = System.IO.Path.Combine(@"C:\UploadFiles\ServerDownloadFiles", request.FileName);
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);
ftp = new Starksoft.Net.Ftp.FtpClient("127.0.0.1"); //remote ftp address
ftp.Open("user", "pass");
// here is waiting for the file to get downloaded from ftp server
System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
ftp.GetFileAsync(request.FileName, stream, true);
stream.Close();
stream.Dispose();
// this will read and be streamed to client
System.IO.FileStream stream2 = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
result.FileName = request.FileName;
result.Length = stream2.Length;
result.FileByteStream = stream2;
}
catch (Exception ex)
{
}
return result;
}
Клиент так:
// start service client
FileTransferClient.TransferServiceClient client = new FileTransferClient.TransferServiceClient();
LogText("Start");
// kill target file, if already exists
string filePath = System.IO.Path.Combine("Download", textBox1.Text);
if (System.IO.File.Exists(filePath)) System.IO.File.Delete(filePath);
// get stream from server
System.IO.Stream inputStream;
string fileName = textBox1.Text;
long length = client.DownloadFile(ref fileName, out inputStream);
// write server stream to disk
using (System.IO.FileStream writeStream = new System.IO.FileStream(filePath, System.IO.FileMode.CreateNew, System.IO.FileAccess.Write))
{
int chunkSize = 2048;
byte[] buffer = new byte[chunkSize];
do
{
// read bytes from input stream
int bytesRead = inputStream.Read(buffer, 0, chunkSize);
if (bytesRead == 0) break;
// write bytes to output stream
writeStream.Write(buffer, 0, bytesRead);
// report progress from time to time
progressBar1.Value = (int)(writeStream.Position * 100 / length);
} while (true);
// report end of progress
LogText("Done!");
writeStream.Close();
}
// close service client
inputStream.Dispose();
client.Close();
что вы думаете?
дубль 2:
Stream stream;
public Stream GetStream(string filename)
{
Starksoft.Net.Ftp.FtpClient ftp = new Starksoft.Net.Ftp.FtpClient();
//string filePath = System.IO.Path.Combine(@"C:\UploadFiles\ServerDownloadFiles", filename);
//System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);
ftp = new Starksoft.Net.Ftp.FtpClient("127.0.0.1");
ftp.Open("testuser", "123456");
stream = new MemoryStream();
ftp.GetFileAsyncCompleted += new EventHandler<Starksoft.Net.Ftp.GetFileAsyncCompletedEventArgs>(ftp_GetFileAsyncCompleted);
this.IsBusy = true;
ftp.GetFileAsync(filename, stream, true);
return stream;
}
Договор на обслуживание:
[ServiceContract]
public interface IStreamingService
{
[OperationContract]
Stream GetStream(string filename);
[OperationContract]
Boolean GetBusyState();
}
Service Config (Binding):
<basicHttpBinding>
<binding name="TransferService" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
<security mode="None">
</security>
</binding>
</basicHttpBinding>