在项目中遇到了这么一个问题。移动端上传的图片,在我asp.net后边接收,但却转换不成图片保存。于是我把接收到的二进制流转换成字符串的形式显示出来。结果大吃一惊。ios传过来的二进制流不是纯图片的,还有一些图片的格式,名称等。
显示如下:
<span style="font-size:18px;">--Boundary+6638A777949A1B1A Content-Disposition: form-data; name="file"; filename="20160523171643.png" Content-Type: image/png �PNG IHDR < m �Su sRGB ��� iDOT 7 ( 7 6 T�gf�� @ IDATxd�ٖ7�e��VW�RJMg2�1�HRY��s{�s`7B�X��`f ����7�����������÷��#���on>�(;���:|ה|�{i=ʮi�������������悲K�PF�����=u�m�ȿ9z������[�}��=������N���k��҇8x���H�S��w�K��x��]p��1��z�9x��͡�m�as{��d��-L�n�閶w�'yH��H��G_w��h�|������ ]�[�J�}ݜp=������hO��,��:5�#y�58ݓ���t�v������<>���#��wo���w� ���}�.��8x����';/7G^lw���ޜ�>|�9�}�9��js��j��e� ��o7gܟ}"}|�9���6_>��|���.:��\��\�W&ei: }��N�'�W� Zկ�ӽ�S~$O(�7�w����tO�|���zwg{�[xt�{ye|R�n��/����I�!�C��� �����A�\y�;��pl��Ci{lߟ��z@�<span style="color:#FF0000;"><strong>(这里的乱码,是图片的数据部分)</strong></span> --Boundary+6638A777949A1B1A-- </span>
<span style="font-size:18px;">using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Text.RegularExpressions; namespace Model { public class MultipartParser { private byte[] requestData; public MultipartParser(Stream stream) { this.Parse(stream, Encoding.UTF8); // ParseParameter(stream, Encoding.UTF8); } public MultipartParser(Stream stream, Encoding encoding) { this.Parse(stream, encoding); } private void Parse(Stream stream, Encoding encoding) { this.Success = false; // Read the stream into a byte array byte[] data = ToByteArray(stream); requestData = data; // Copy to a string for header parsing string content = encoding.GetString(data); // The first line should contain the delimiter int delimiterEndIndex = content.IndexOf("\r\n"); if (delimiterEndIndex > -1) { string delimiter = content.Substring(0, content.IndexOf("\r\n")); // Look for Content-Type Regex re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)"); Match contentTypeMatch = re.Match(content); // Look for filename re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")"); Match filenameMatch = re.Match(content); // Did we find the required values? if (contentTypeMatch.Success && filenameMatch.Success) { // Set properties this.ContentType = contentTypeMatch.Value.Trim(); this.Filename = filenameMatch.Value.Trim(); // Get the start & end indexes of the file contents int startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length; byte[] delimiterBytes = encoding.GetBytes("\r\n" + delimiter); int endIndex = IndexOf(data, delimiterBytes, startIndex); int contentLength = endIndex - startIndex; // Extract the file contents from the byte array byte[] fileData = new byte[contentLength]; Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength); this.FileContents = fileData; this.Success = true; } } } private void ParseParameter(Stream stream, Encoding encoding) { this.Success = false; // Read the stream into a byte array byte[] data; if (requestData.Length == 0) { data = ToByteArray(stream); } else { data = requestData; } // Copy to a string for header parsing string content = encoding.GetString(data); // The first line should contain the delimiter int delimiterEndIndex = content.IndexOf("\r\n"); if (delimiterEndIndex > -1) { string delimiter = content.Substring(0, content.IndexOf("\r\n")); string[] splitContents = content.Split(new[] {delimiter}, StringSplitOptions.RemoveEmptyEntries); foreach (string t in splitContents) { // Look for Content-Type Regex contentTypeRegex = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)"); Match contentTypeMatch = contentTypeRegex.Match(t); // Look for name of parameter Regex re = new Regex(@"(?<=name\=\"")(.*)"); Match name = re.Match(t); // Look for filename re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")"); Match filenameMatch = re.Match(t); // Did we find the required values? if (name.Success || filenameMatch.Success) { // Set properties //this.ContentType = name.Value.Trim(); int startIndex; if (filenameMatch.Success) { this.Filename = filenameMatch.Value.Trim(); } if(contentTypeMatch.Success) { // Get the start & end indexes of the file contents startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length; } else { startIndex = name.Index + name.Length + "\r\n\r\n".Length; } //byte[] delimiterBytes = encoding.GetBytes("\r\n" + delimiter); //int endIndex = IndexOf(data, delimiterBytes, startIndex); //int contentLength = t.Length - startIndex; string propertyData = t.Substring(startIndex - 1, t.Length - startIndex); // Extract the file contents from the byte array //byte[] paramData = new byte[contentLength]; //Buffer.BlockCopy(data, startIndex, paramData, 0, contentLength); MyContent myContent = new MyContent(); myContent.Data = encoding.GetBytes(propertyData); myContent.StringData = propertyData; myContent.PropertyName = name.Value.Trim(); if (MyContents == null) MyContents = new List<MyContent>(); MyContents.Add(myContent); this.Success = true; } } } } private int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex) { int index = 0; int startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex); if (startPos != -1) { while ((startPos + index) < searchWithin.Length) { if (searchWithin[startPos + index] == serachFor[index]) { index++; if (index == serachFor.Length) { return startPos; } } else { startPos = Array.IndexOf<byte>(searchWithin, serachFor[0], startPos + index); if (startPos == -1) { return -1; } index = 0; } } } return -1; } private byte[] ToByteArray(Stream stream) { byte[] buffer = new byte[32768]; using (MemoryStream ms = new MemoryStream()) { while (true) { int read = stream.Read(buffer, 0, buffer.Length); if (read <= 0) return ms.ToArray(); ms.Write(buffer, 0, read); } } } public List<MyContent> MyContents { get; set; } public bool Success { get; private set; } public string ContentType { get; private set; } public string Filename { get; private set; } public byte[] FileContents { get; private set; } } public class MyContent { public byte[] Data { get; set; } public string PropertyName { get; set; } public string StringData { get; set; } } } </span>
<span style="font-size:18px;">using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace ITSMToJson { public partial class updateFile: System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //假数据 //FileStream photo = new FileStream("d://test.jpg", FileMode.Open); //byte[] buffer = new byte[photo.Length]; //photo.Read(buffer, 0, buffer.Length); //获得IOS传过来的二进制流 Stream sourceStream = Request.InputStream; MultipartParser model = new MultipartParser(sourceStream);//实例化MultipartParse string Filename = model.Filename; //获得图片名称 byte[] FileContents = model.FileContents; //获得图片流数据 //获得Web服务上File虚拟路径相对应的物理文件路径 string Path = HttpContext.Current.Server.MapPath("/File") + "//" + DateTime.Now.ToString("yyyyMMdd"); //查看路径是否存在,如果不存在,则创建路径 if (!Directory.Exists(Path)) { DirectoryInfo foler = Directory.CreateDirectory(Path); } //得到要目的文件路径 string filenameaddress = Path+"//"+Filename; //将图片流显示成图片并保存起来 FileStream targetStream = new FileStream(filenameaddress, FileMode.Create); targetStream.Write(FileContents, 0, FileContents.Length); System.Drawing.Image img = System.Drawing.Image.FromStream(targetStream); targetStream.Close(); sourceStream.Close(); } } }</span>
在此还要感谢提供思路和代码的网友。代码就是不断地积累,还要不断总结经验和技术,分享给大家。