将上传的文件转成二进制流, 然后再解析成文件保存,为什么文件损坏了。。

星光灭绝SLE 2014-09-02 10:53:01
做了个试验 通过二进制流的方法来传递中小型文件。。。


//web上传文件,然后转成byte
HttpFileCollection files = context.Request.Files;
HttpPostedFile file = files[0];
string fileName = file.FileName;
//fileName = context.Server.MapPath("~/uploaded/" + fileName);
//file.SaveAs(fileName); //如果这里save的话,我查看过文件是完好的,可以打开
Stream fs = file.InputStream;
BinaryReader br = new BinaryReader(fs);
byte[] bytes = br.ReadBytes((Int32)fs.Length);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();

//将byte[]转回成文件
FileStream fs2 = new FileStream("e:\\abc\\" + file.FileName, FileMode.Create, FileAccess.Write);
fs2.Write(buffer, 0, buffer.Length);
fs2.Flush();
fs2.Close();
//转回形成的文件,文件大小没变,但不能用(图片渲染不来,音频文件播放器解析不出来)。。。。




我在网上查出来的方法都是,先保存在服务器,然后filestream读这个文件,转成二进制,再传输
我不想经过这步I/O,感觉这一步浪费资源啊。。。。

我想直接将HttpPostedFile里的内容传递给别人,比如放一个web service接口专门获取文件二进制流,然后将二进制转成文件保存起来的。所以才有了上面的写法。

不知道要实现我的想法,各位大神有没什么高招。。。。
...全文
2237 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
儒林新风 2018-07-27
  • 打赏
  • 举报
回复
从你这获取了灵感,给你个模拟post表单方法:
        /// <summary>  
/// 使用Post方法获取字符串结果
/// </summary>
/// <param name="url"></param>
/// <param name="formItems">Post表单内容</param>
/// <param name="cookieContainer"></param>
/// <param name="timeOut">默认30秒</param>
/// <param name="encoding">响应内容的编码类型(默认utf-8)</param>
/// <returns></returns>
public static string PostForm(string url, List<FormItemModel> formItems, CookieContainer cookieContainer = null, string refererUrl = null, Encoding encoding = null, int timeOut = 30000)
{
string retString = "";
HttpWebRequest request = null;
try
{
request = (HttpWebRequest)WebRequest.Create(url);
#region 初始化请求对象
request.Method = "POST";
request.Timeout = timeOut;
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.KeepAlive = true;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";
if (!string.IsNullOrEmpty(refererUrl))
request.Referer = refererUrl;
if (cookieContainer != null)
request.CookieContainer = cookieContainer;
#endregion
string boundary = "----" + DateTime.Now.Ticks.ToString("x");//分隔符
request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
//请求流
var postStream = new MemoryStream();
#region 处理Form表单请求内容
//是否用Form上传文件
var formUploadFile = formItems != null && formItems.Count > 0;
if (formUploadFile)
{
//文件数据模板
string fileFormdataTemplate =
"\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" +
"\r\nContent-Type: application/octet-stream" +
"\r\n\r\n";
//文本数据模板
string dataFormdataTemplate =
"\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\"" +
"\r\n\r\n{1}";
foreach (var item in formItems)
{
string formdata = null;
if (item.IsFile)
{
//上传文件
formdata = string.Format(
fileFormdataTemplate,
item.Key, //表单键
item.FileName);
}
else
{
//上传文本
formdata = string.Format(
dataFormdataTemplate,
item.Key,
item.Value);
}
//统一处理
byte[] formdataBytes = null;
//第一行不需要换行
if (postStream.Length == 0)
formdataBytes = Encoding.UTF8.GetBytes(formdata.Substring(2, formdata.Length - 2));
else
formdataBytes = Encoding.UTF8.GetBytes(formdata);
postStream.Write(formdataBytes, 0, formdataBytes.Length);

//写入文件内容
if (item.FileContent != null && item.FileContent.Length > 0)
{
using (var stream = item.FileContent)
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
postStream.Write(buffer, 0, bytesRead);
}
}
}
}
//结尾
var footer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
postStream.Write(footer, 0, footer.Length);
}
else
{
request.ContentType = "application/x-www-form-urlencoded";
}
#endregion
request.ContentLength = postStream.Length;
#region 输入二进制流
if (postStream != null)
{
postStream.Position = 0;
//直接写入流
Stream requestStream = request.GetRequestStream();
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = postStream.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
postStream.Close();//关闭文件访问
}
#endregion
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (cookieContainer != null)
{
response.Cookies = cookieContainer.GetCookies(response.ResponseUri);
}
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader myStreamReader = new StreamReader(responseStream, encoding ?? Encoding.UTF8))
{
retString = myStreamReader.ReadToEnd();
}
}
}
catch (Exception ex)
{
LogHelper.WriteLog(MethodBase.GetCurrentMethod().ReflectedType.FullName + "." + MethodBase.GetCurrentMethod().Name + ";", ex);

}
finally
{
if (request != null)
{
request.Abort();
}
}
return retString;
}




public class FormItemModel
{
/// <summary>
/// 表单键,request["key"]
/// </summary>
public string Key { set; get; }

/// <summary>
/// 表单值,上传文件时可以忽略,request["key"].value
/// </summary>
public string Value { set; get; }

/// <summary>
/// 是否是文件
/// </summary>
public bool IsFile
{
get
{
if (FileContent == null || FileContent.Length == 0)
return false;

if (FileContent != null && FileContent.Length > 0 && string.IsNullOrWhiteSpace(FileName))
throw new Exception("上传文件时 FileName 属性值不能为空");
return true;
}
}

/// <summary>
/// 上传的文件名
/// </summary>
public string FileName { set; get; }

/// <summary>
/// 上传的文件内容
/// </summary>
public Stream FileContent { set; get; }
}

aa18768493436 2016-12-28
  • 打赏
  • 举报
回复
弱弱的问一句,问题解决了么
星光灭绝SLE 2014-09-03
  • 打赏
  • 举报
回复
HttpPostedFile类里的内容 没办法直接转成二进制存在byte[]中么。。。 难道必须要先保存下来,然后filestream读取这个文件才能转成二进制?
星光灭绝SLE 2014-09-03
  • 打赏
  • 举报
回复
引用 9 楼 caozhy 的回复:
说明文件开头就没有写对。贴出UltraEdit显示的两个文件的开头一段。





确实不一样,
Stream fs = file.InputStream;
BinaryReader br = new BinaryReader(fs);
byte[] bytes = br.ReadBytes((Int32)fs.Length);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
这一步的问题?
threenewbee 2014-09-03
  • 打赏
  • 举报
回复
说明文件开头就没有写对。贴出UltraEdit显示的两个文件的开头一段。
星光灭绝SLE 2014-09-03
  • 打赏
  • 举报
回复
引用 6 楼 caozhy 的回复:
关键是让你看有什么差异。


额。。。 好像唯一的区别就是 :
.\100吧主候选人.jpg different (E:\abc\100吧主候选人.jpg is more recent)





但保存出来的文件确实是损坏的:
星光灭绝SLE 2014-09-03
  • 打赏
  • 举报
回复
引用 5 楼 wangnaisheng 的回复:
在你的fs.Read(buffer, 0, buffer.Length); 下面加一句: fs.Seek(0, SeekOrigin.Begin); 试试

            byte[] bytes = br.ReadBytes((Int32)fs.Length);
            byte[] buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Seek(0, SeekOrigin.Begin);
            fs.Close();
没用,出来的文件还是损坏的
threenewbee 2014-09-03
  • 打赏
  • 举报
回复
引用 4 楼 starlightextinction 的回复:
[quote=引用 2 楼 caozhy 的回复:] 用windiff或者ultraedit比较下两个文件,看哪里的问题。
打开后像天书一样。。。看不懂。。。。 就我这个思路,上面的代码写法上有问题吗?[/quote] 关键是让你看有什么差异。
wangnaisheng 2014-09-03
  • 打赏
  • 举报
回复
在你的fs.Read(buffer, 0, buffer.Length); 下面加一句: fs.Seek(0, SeekOrigin.Begin); 试试
星光灭绝SLE 2014-09-03
  • 打赏
  • 举报
回复
引用 2 楼 caozhy 的回复:
用windiff或者ultraedit比较下两个文件,看哪里的问题。
打开后像天书一样。。。看不懂。。。。 就我这个思路,上面的代码写法上有问题吗?
星光灭绝SLE 2014-09-03
  • 打赏
  • 举报
回复
引用 1 楼 rayyu1989 的回复:
传输是 MemoryStream 并没有用到io 保存才io
System.IO.MemoryStream fs = file.InputStream; 能转?
1988525 2014-09-03
  • 打赏
  • 举报
回复
HttpFileCollection files = context.Request.Files; HttpPostedFile file = files[0]; int upPhotoLength = files.ContentLength; byte[] PhotoArray = new Byte[upPhotoLength]; Stream PhotoStream = files.InputStream; PhotoStream.Read(PhotoArray, 0, upPhotoLength);
三楼の郎 2014-09-03
  • 打赏
  • 举报
回复
引用 11 楼 starlightextinction 的回复:
HttpPostedFile类里的内容 没办法直接转成二进制存在byte[]中么。。。 难道必须要先保存下来,然后filestream读取这个文件才能转成二进制?
你去看看HttpWorkerRequest类吧,可以通过GetPreloadedEntityBody、ReadEntityBody方法在预加载阶段提前读取到客户端提交的数据,这里取出来的就是byte[],不过需要你自行从中分离出属于文件内容的部分
  • 打赏
  • 举报
回复

using (Stream output = File.OpenWrite("c:\temp\file.zip"))
                    using (Stream input = file.InputStream)
                    {
                        byte[] buffer = new byte[8192];
                        int bytesRead;
                        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            output.Write(buffer, 0, bytesRead);
                        }
                    }
把上面的File.OpenWrite换成file.InputStream http://stackoverflow.com/questions/12927932/file-upload-with-c-sharp-and-streaming
threenewbee 2014-09-02
  • 打赏
  • 举报
回复
用windiff或者ultraedit比较下两个文件,看哪里的问题。
rayyu1989 2014-09-02
  • 打赏
  • 举报
回复
传输是 MemoryStream 并没有用到io 保存才io

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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