做了几天的Javascript与webservice的对接传输文件的代码,一直就是没有成功把文件完整的上传。
郁闷的时间,我不停地想文件的编码格式,流的传输格式。最终,我找到了答案。关键点在于Javascript传输二进制流的方法(在仅有HTTPRequest插件的时候,因为这个插件传输的只能是UTF8格式的字符流,而恰恰这就是关键)。二进制流到UTF8字符流转码未必都能成功得转换成功,所以在这里我们只能把每个二进制值的大小用字符标识,而字符是可以完整的传输成功;到服务器端再反转化为二进制流(即把字符流的表示数值大小转化为二进制表示的字节码,直接写入文件保存即可)。这样就不会产生转码错误的几率。
Javascript:代码
1.读入文件二进制流,转化为字符串流,便于Javascript传送。
var form = document.forms["form1"];
if (form["file"].files.length > 0) { //0 start
// 寻找表单域中的 <input type="file" ... /> 标签
var file = form["file"].files[0];
// try sending
var reader = new FileReader();
reader.onloadend = function () { //1 start
// 这个事件在读取结束后,无论成功或者失败都会触发
if (reader.error) {
alert(reader.error);
} else {
// 构造 XMLHttpRequest 对象,发送文件 Binary 数据
var xhr = new XMLHttpRequest();
xhr.open("POST", "pictrueUpload.ashx?filename=" + file.name, true);
xhr.setRequestHeader("Content-type", "application/octet-stream");
xhr.send(ParseString(reader.result));
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText);
}
}
}
} // if (reader.error)
} //1 end
// reader.readAsText(file);
reader.readAsBinaryString(file);
其中ParseString(stringToParse)的代码如下:
//编码二进制到字符流
function ParseString(stringToParse) {
var stringParsed = "";
for (var i = 0; i < stringToParse.length; i++) {
stringParsed += stringToParse.charCodeAt(i);
if (i == stringToParse.length - 1) {
break;
}
stringParsed += "|";
}
return stringParsed.toString();
}
C#:代码
1.先接收字符串,转化为纯正的二进制字节码数组
int vals = context.Request.TotalBytes;
byte[] bytes = context.Request.BinaryRead(vals);
string strContent = System.Text.Encoding.UTF8.GetString(bytes);
string[] stringCodes = strContent.Split('|');
byte[] byteParsed = new byte[stringCodes.Length];
for (int stringCodeCount = 0; stringCodeCount < stringCodes.Length; stringCodeCount++)
{
byteParsed[stringCodeCount] = Convert.ToByte(stringCodes[stringCodeCount]);
}
2.把字节码数组直接写入你创建的文件里面
string imgname = "";
try
{
imgname = context.Request.Params["filename"];//DateTime.Now.ToString("yyyyMMddhhmmss") + ".jpg"
}
catch (Exception e)
{
context.Response.Write(e.ToString());
return;
}
string path = "/UpPhoto/";
//路径
string toFileFullPath = context.Server.MapPath(path);
//检查是否有该路径 没有就创建
if (!Directory.Exists(toFileFullPath))
{
try
{
Directory.CreateDirectory(toFileFullPath);
}
catch (Exception e)
{
context.Response.Write(e.ToString());
return;
}
}
path += imgname;
try
{
FileStream fs = new FileStream(context.Server.MapPath(path), FileMode.Create, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(byteParsed);
bw.Close();
fs.Close();
}
catch (Exception e)
{
context.Response.Write(e.ToString());
return;
}