在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
>
|
原文链接:点击打开链接