WCF教程--使用流Stream进行文件的上传下载

来源:互联网 发布:arm数组累加 编辑:程序博客网 时间:2024/05/16 07:27

在wpf项目中,区分客户端和服务端,需要2端进行数据同步和文件传输。

wcf 文件上传的例子网上很多,我也是借鉴别人的示例。wcf 文件下载的示例网上就很少了,不知道是不是因为两者的处理方式比较类似,别人就没有再上传了。 

WCF 支持传送二进制流数据,但有一定的限制。

只有 BasicHttpBinding、WebHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 支持传送流数据。

流数据类型必须是可序列化的 Stream 或 MemoryStream。

传递时消息体(Message Body)中不能包含其他数据。

参考:http://www.csharpwin.com/csharpspace/10780r501.shtml 

1 定义接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
IUploadFile.cs
[ServiceContract]
    public interface IUploadFile
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        [OperationContract(Action = "UploadFile", IsOneWay = true)]
        void UploadFileMethod(FileUploadMessage myFileMessage);
        /// <summary>
        /// 获取文件列表
        /// </summary>
        [OperationContract]
        string[] GetFilesList();
        /// <summary>
        /// 下载文件
        /// </summary>
        [OperationContract]
        Stream DownLoadFile(string fileName);
    }
    [MessageContract]
    public class FileUploadMessage
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName;
        [MessageBodyMember(Order = 1)]
        public Stream FileData;
    }

2.实现接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
UploadFile.svc.cs
public class UploadFile : IUploadFile
    {
        /// <summary>
        /// 服务器地图文件保存路径
        /// </summary>
        private string savePath = @"D:\矿车定位上传地图备份";
        /// <summary>
        /// 上传文件
        /// </summary>
        public void UploadFileMethod(FileUploadMessage myFileMessage)
        {
            if(!Directory.Exists(savePath))//地图存放的默认文件夹是否存在
            {
                Directory.CreateDirectory(savePath);//不存在则创建
            }
            string fileName = myFileMessage.FileName;//文件名
            string fileFullPath = Path.Combine(savePath, fileName);//合并路径生成文件存放路径
            Stream sourceStream = myFileMessage.FileData;
            if (sourceStream == null) { return; }
            if (!sourceStream.CanRead) { return; }
            //创建文件流,读取流中的数据生成文件
            using (FileStream fs = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                try
                {
                    const int bufferLength = 4096;
                    byte[] myBuffer = new byte[bufferLength];//数据缓冲区
                    int count;
                    while ((count = sourceStream.Read(myBuffer, 0, bufferLength)) > 0)
                    {
                        fs.Write(myBuffer, 0, count);
                    }
                    fs.Close();
                    sourceStream.Close();
                }
                catch return; }
            }
        }
        /// <summary>
        /// 获取文件列表
        /// </summary>
        public string[] GetFilesList()
        {
            if(!Directory.Exists(savePath))//判断文件夹路径是否存在
            {
                return null;
            }
            DirectoryInfo myDirInfo = new DirectoryInfo(savePath);
            FileInfo[] myFileInfoArray = myDirInfo.GetFiles("*.zip");
            string[] myFileList = new string[myFileInfoArray.Length];
            //文件排序
            for (int i = 0; i < myFileInfoArray.Length - 1;i++ )
            {
                for (int j = i + 1; j < myFileInfoArray.Length; j++)
                {
                    if(myFileInfoArray[i].LastWriteTime > myFileInfoArray[j].LastWriteTime)
                    {
                        FileInfo myTempFileInfo = myFileInfoArray[i];
                        myFileInfoArray[i] = myFileInfoArray[j];
                        myFileInfoArray[j] = myTempFileInfo;
                    }
                }
            }
            for (int i = 0; i < myFileInfoArray.Length; i++)
            {
                myFileList[i] = myFileInfoArray[i].Name;
            }
            return myFileList;
        }
        /// <summary>
        /// 下载地图
        /// </summary>
        public Stream DownLoadFile(string fileName)
        {
            string fileFullPath = Path.Combine(savePath, fileName);//服务器文件路径
            if(!File.Exists(fileFullPath))//判断文件是否存在
            {
                return null;
            }
            try
            {
                Stream myStream = File.OpenRead(fileFullPath);
                return myStream;
            }
            catch return null; }
        }
    }

3.配置上传文件大小限制:

4.客户端上传文件方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
客户端上传文件方法
/// <summary>
        /// 上传文件
        /// </summary>
        public void UploadFileMethod(string fileName,string fileFullPath)
        {
            UploadFile_WcfService.FileUploadMessage myFileMessage = new DataProcess.UploadFile_WcfService.FileUploadMessage();
            myFileMessage.FileName = fileName;//文件名
            using (FileStream fs = File.OpenRead(fileFullPath))
            {
                myFileMessage.FileData = fs;
                UploadFile_WcfService.IUploadFile myService = myClient.ChannelFactory.CreateChannel();
                try
                {
                    myService.UploadFileMethod(myFileMessage);
                }
                catch { }
                //关闭流
                fs.Close();
            }
        }

客户端下载方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
客户端下载文件方法
isExit = false;//该变量是窗体是否关闭的标志,如果窗体关闭置为true,跳出写文件循环
//下载地图文件保存路径
            string saveFilePath = saveFilePathObj.ToString();
            //从服务器中获取地图文件流
            Stream sourceStream = myUploadFileClass.DownloadFile(fileNameChecked);
            if (sourceStream != null)
            {
                if (sourceStream.CanRead)
                {
                    using (FileStream fs = new FileStream(saveFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        const int bufferLength = 4096;
                        byte[] myBuffer = new byte[bufferLength];
                        int count;
                        while ((count = sourceStream.Read(myBuffer, 0, bufferLength)) > 0)
                        {
                            if (isExit == false)
                            {
                                fs.Write(myBuffer, 0, count);
                            }
                            else//窗体已经关闭跳出循环
                            {
                                break;
                            }
                        }
                        fs.Close();
                        sourceStream.Close();
                    }
                }
            }

上面的配置上传一些比较大的文件应该是没有问题了,如果需要下载大文件还需要在客户端的app.config 中设置如下配置,此处的重点是设置transferMode="Streamed"默认是Buffered
,如果是Buffered是无法设置较大的maxReceivedMessageSize="9223372036854775807"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 <behaviors>
      <serviceBehaviors>
        <behavior name="DefaultBehavior">
          <serviceDe<a href="http://www.suchso.com/programmer/chengxuyuan-duanzi-bug-shangwang.html" class="keylink" title=" Bug修复" target="_blank">bug</a> includeExceptionDetailInFaults="true" />
          <serviceMetadata httpGetEnabled="true"  httpGetUrl="http://192.168.20.94:8091/SyncDataService/mex"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name="TcpBindingConfig" maxBufferPoolSize="524288000" maxBufferSize="65536000" maxReceivedMessageSize="65536000" transferMode="Streamed">
          <security mode="None" />
        </binding>
      </netTcpBinding>
      <basicHttpBinding>
        <binding name="BasicHttpBindingConfig" maxBufferPoolSize="524288000" maxBufferSize="65536000" maxReceivedMessageSize="65536000" sendTimeout="00:02:00" transferMode="Streamed">
          <security mode="None"/>
        </binding>
      </basicHttpBinding>
    </bindings>


原文链接:点击打开链接

0 0
原创粉丝点击