请问高人:如何使用Ws-Attachment/DIME实现java client与.net web service间的large size文件的传输(up有分)

yp2211 2004-07-23 03:13:37
如题。
参考资料:
http://www.microsoft.com/china/msdn/archives/library/dnwebsrv/html/wsedime.asp
http://www-900.ibm.com/developerWorks/cn/webservices/ws-dime/index.shtml#Introduction
...全文
155 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
龙豆2211 2004-08-26
  • 打赏
  • 举报
回复
使用 DimeReader 和 DimeWriter 对数据进行流处理

DIME 是一种基于消息的格式,DIME 记录被序列化和可以分块的事实使它能够通过数据包级传输协议(如 TCP 和 UDP)高效使用。WSE 1.0 支持 DIME 消息和 System.IO.Stream 对象(如 NetworkStream)之间的双向流处理,而不受基于消息的协议(如 HTTP)的限制。当作为 DIME 流处理时,WSE 运行时将传出的 DIME 记录分块,这样就无需定义被进行流处理的对象大小。当到达流结尾处时,写入最后的记录块。下面的示例从一个文件(如大型二进制图像文件)生成输入流,将该流写到一系列的分块 DIME 记录中,并将 DIME 消息写到一个 Stream 对象中,这个对象可以是通过 TCP 传输的 NetworkStream:

// 将二进制输入流采样转换成指定 MIME 媒体类型的
// DIME 流。
static void WriteToDime(Stream inputStr,Stream dimeStr,string mediaType)
{
// 创建写入器,用于将 DIME 消息写入 dimeStream
DimeWriter myDW = new DimeWriter(dimeStr);

// 创建 GUID,用作 DIME 记录 ID。
Guid guid = Guid.NewGuid();
string id = string.Format("uuid:{0}", guid.ToString());

// 创建新的 DIME 记录,其 MIME 媒体类型由
// mediaType 指定,并且用 contentLength 值 -1 来指定分块。
DimeRecord myRecord = myDW.LastRecord(id, mediaType,
TypeFormatEnum.MediaType, -1);

// 指定很小的记录块:4KB。
myRecord.ChunkSize = 4096;

// 使用 BinaryWriter 将流写入 DimeRecord。
BinaryWriter myWriter = new BinaryWriter(myRecord.BodyStream);

// 将传入流中的内容写入 BinaryWriter。
int size = 4096;
byte[] bytes = new byte[4096];
int numBytes;
while((numBytes = inputStr.Read(bytes, 0, size)) > 0)
{
myWriter.Write(bytes, 0, numBytes);
}

// 清理
myDW.Close();
}

值得注意的是,基于 SOAP 的 DIME 实现是将整个 DIME 消息读入内存,而对 DIME 进行流处理时,可以使用 DimeRecord.ChunkSize 来限制需要使用的内存量。

以下方法实现了相反的过程,即读取 DIME 流,并将记录内容提取到二进制流中。

static void ReadFromDime(Stream dimeStr, Stream outStr)
{
// 创建读取器,用于读取流式 DIME 消息。
DimeReader myDR = new DimeReader(dimeStr);

// 创建 DimeRecord,以便(仅)读取当前的 DIME 记录。
DimeRecord myRecord = myDR.ReadRecord();

// 创建读取器,以便将记录内容读到其中。
BinaryReader myReader = new BinaryReader(myRecord.BodyStream);

// 将内容写到输出流中。
int size = 4096;
byte[] bytes = new byte[4096];
int numBytes;
while((numBytes = myReader.Read(bytes, 0, size)) > 0)
{
outStr.Write(bytes, 0, numBytes);
}

// 清理
myReader.Close();
myDR.Close();
}
yp2211 2004-08-26
  • 打赏
  • 举报
回复
up
yp2211 2004-07-24
  • 打赏
  • 举报
回复
哥哥们,多费神,拉兄弟一把啊
yp2211 2004-07-23
  • 打赏
  • 举报
回复
如果服务端这么写可以传输文件,但由于 ASP.NET WebMethods 不支持流,因此在 ASP.NET 中使用 WSE 时,整个 DIME 消息都会被缓存到内存中,这样大尺寸的文件无法传输。请大家帮帮忙想想办法啊,郁闷了
[WebMethod]
public string PutData(string originalName)
{
SoapContext ctx = HttpSoapContext.RequestContext;
if (ctx.Attachments.Count == 0)
{
throw new SoapException("Attachments required ------ kyjb.",
new XmlQualifiedName("Client",
"http://schemas.xmlsoap.org/soap/envelope"));
}
FileStream fs = new FileStream("H:\\" + originalName
/*Server.MapPath("incoming/" + originalName)*/,
FileMode.CreateNew, FileAccess.Write, FileShare.None);
byte[] buf = new byte[ctx.Attachments[0].Stream.Length];
ctx.Attachments[0].Stream.Read(buf, 0, buf.Length);
fs.Write(buf, 0, buf.Length);
fs.Close();
return "http://localhost/WSEDIME/incoming/" + originalName;
}

[WebMethod]
public string GetData(string originalName)
{
SoapContext responseContext = HttpSoapContext.ResponseContext;
string retUri = null;
string filePath = "E:\\" + originalName;

System.IO.Stream iStream = null;

// Open the file.
iStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open,
System.IO.FileAccess.Read,System.IO.FileShare.Read);

// Read the bytes.
DimeAttachment dimeImage = new DimeAttachment("text/richtext", TypeFormatEnum.MediaType, iStream);

// 指定很小的记录块:4KB。
dimeImage.ChunkSize = 4096;

dimeImage.Id = "uri:" + Guid.NewGuid().ToString();

// Verify that the client is connected.
responseContext.Attachments.Add(dimeImage);

retUri = dimeImage.Id;

return retUri;
}

12,162

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 Web Services
社区管理员
  • Web Services社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧