算术运算导致溢出错误 - 对于 c# 中的 byte[] 数组
我在 c# 中有这一行:
byte[] bytes = new byte[streamReader.BaseStream.Length];
该长度返回大于 4 GB 的文件大小。
在该行我有以下错误:
Arithmetic operation resulted in an overflow.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.OverflowException: Arithmetic operation resulted in an overflow.
Source Error:
Line 41: System.IO.BinaryReader br = new System.IO.BinaryReader(streamReader.BaseStream);
Line 42:
Line 43: byte[] bytes = new byte[streamReader.BaseStream.Length];
Line 44:
Line 45: br.Read(bytes, 0, (int)streamReader.BaseStream.Length);
我该如何修复此错误?
编辑
我正在使用 .net 4
该代码是下载文件处理程序的一部分,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using WindowsServer.Classes;
namespace WindowsServer
{
/// <summary>
/// Summary description for HandlerForMyFE
/// </summary>
public class Handler : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
private HttpContext _context;
private HttpContext Context
{
get
{
return _context;
}
set
{
_context = value;
}
}
public void ProcessRequest(HttpContext context)
{
Context = context;
string filePath = context.Request.QueryString["Downloadpath"];
filePath = context.Server.MapPath(filePath);
if (filePath == null)
{
return;
}
System.IO.StreamReader streamReader = new System.IO.StreamReader(filePath);
System.IO.BinaryReader br = new System.IO.BinaryReader(streamReader.BaseStream);
byte[] bytes = new byte[streamReader.BaseStream.Length];
br.Read(bytes, 0, (int)streamReader.BaseStream.Length);
if (bytes == null)
{
return;
}
streamReader.Close();
br.Close();
string fileName = System.IO.Path.GetFileName(filePath);
string MimeType = GetMimeType(fileName);
string extension = System.IO.Path.GetExtension(filePath);
char[] extension_ar = extension.ToCharArray();
string extension_Without_dot = string.Empty;
for (int i = 1; i < extension_ar.Length; i++)
{
extension_Without_dot += extension_ar[i];
}
string filesize = string.Empty;
FileInfo f = new FileInfo(filePath);
filesize = f.Length.ToString();
//DownloadFile.DownloadFileMethod_2(Context, filePath, 5242880);
WriteFile(bytes, fileName, filesize, MimeType + " " + extension_Without_dot, context.Response);
}
private void WriteFile(byte[] content, string fileName, string filesize, string contentType, HttpResponse response)
{
response.Buffer = true;
response.Clear();
response.ContentType = contentType;
response.AddHeader("content-disposition", "attachment; filename=" + fileName);
response.AddHeader("Content-Length", filesize);
response.BinaryWrite(content);
response.Flush();
response.End();
}
private string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
mimeType = regKey.GetValue("Content Type").ToString();
return mimeType;
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
提前致谢
i have this line in c# :
byte[] bytes = new byte[streamReader.BaseStream.Length];
That Length returns a file size bigger than 4 GB.
at that line i have the Error below :
Arithmetic operation resulted in an overflow.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.OverflowException: Arithmetic operation resulted in an overflow.
Source Error:
Line 41: System.IO.BinaryReader br = new System.IO.BinaryReader(streamReader.BaseStream);
Line 42:
Line 43: byte[] bytes = new byte[streamReader.BaseStream.Length];
Line 44:
Line 45: br.Read(bytes, 0, (int)streamReader.BaseStream.Length);
how can i fix this error ?
edit
i am using .net 4
that code was part of a handler for download files like below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using WindowsServer.Classes;
namespace WindowsServer
{
/// <summary>
/// Summary description for HandlerForMyFE
/// </summary>
public class Handler : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
private HttpContext _context;
private HttpContext Context
{
get
{
return _context;
}
set
{
_context = value;
}
}
public void ProcessRequest(HttpContext context)
{
Context = context;
string filePath = context.Request.QueryString["Downloadpath"];
filePath = context.Server.MapPath(filePath);
if (filePath == null)
{
return;
}
System.IO.StreamReader streamReader = new System.IO.StreamReader(filePath);
System.IO.BinaryReader br = new System.IO.BinaryReader(streamReader.BaseStream);
byte[] bytes = new byte[streamReader.BaseStream.Length];
br.Read(bytes, 0, (int)streamReader.BaseStream.Length);
if (bytes == null)
{
return;
}
streamReader.Close();
br.Close();
string fileName = System.IO.Path.GetFileName(filePath);
string MimeType = GetMimeType(fileName);
string extension = System.IO.Path.GetExtension(filePath);
char[] extension_ar = extension.ToCharArray();
string extension_Without_dot = string.Empty;
for (int i = 1; i < extension_ar.Length; i++)
{
extension_Without_dot += extension_ar[i];
}
string filesize = string.Empty;
FileInfo f = new FileInfo(filePath);
filesize = f.Length.ToString();
//DownloadFile.DownloadFileMethod_2(Context, filePath, 5242880);
WriteFile(bytes, fileName, filesize, MimeType + " " + extension_Without_dot, context.Response);
}
private void WriteFile(byte[] content, string fileName, string filesize, string contentType, HttpResponse response)
{
response.Buffer = true;
response.Clear();
response.ContentType = contentType;
response.AddHeader("content-disposition", "attachment; filename=" + fileName);
response.AddHeader("Content-Length", filesize);
response.BinaryWrite(content);
response.Flush();
response.End();
}
private string GetMimeType(string fileName)
{
string mimeType = "application/unknown";
string ext = System.IO.Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (regKey != null && regKey.GetValue("Content Type") != null)
mimeType = regKey.GetValue("Content Type").ToString();
return mimeType;
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您将不得不使用较小的缓冲区并逐段读取流。我认为您无法创建大于 4 GB 的字节数组。
如果您使用的是 .NET 4,则可以使用新的 Stream.CopyTo(Stream) 实例方法将输入流复制到输出流。
You're going to have to use a smaller buffer and read the stream piecemeal. I don't think you're going to be able to create a byte array that's bigger than 4 GB.
If you're using .NET 4, you can use the new Stream.CopyTo(Stream) instance method to copy the input stream to an output stream.
在 .NET 中,您可以分配的最大对象约为 2GB。引自文档:
还有一篇来自 CLR 的博客文章团队。
当然2GB是理论极限。实际限制较低。所以你必须分块阅读:
而且你的代码看起来有点奇怪。您有一个处理编码字符串的 StreamReader,但您正在使用字节数组和 BinaryReader。看起来有点奇怪。
In .NET the largest object you could allocate is around 2GB. Quote from the documentation:
There is also a blog post from the CLR team.
Of course 2GB is the theoretical limit. The practical limit is lower. So you will have to read this in chunks:
Also your code seems a bit strange. You have a StreamReader which processes encoded strings and yet you are working with byte arrays and BinaryReaders. Seems kinda strange.
.NET 中的数组不能容纳超过 2^31 个元素 (
System.Int32.MaxValue
) 或 最大大小为 2 GB,大致相当于 2 GB 字节数组。有关解决方法,请参阅 http://blogs.msdn.com /b/joshwil/archive/2005/08/10/450202.aspx
另一种选择是使用
MemoryMappedFile
和 Streams - 这将允许访问以下文件任何大小...要使下载代码工作,您可以读取一个块,发送它,读取下一个块等。或者使用
Stream
读取和写入OutputStream
没有任何中间缓冲区...另一种选择是使用
TransmitFile
其中可以处理文件> 4GB。编辑 - 根据评论:
您可以将后面的代码替换
为
OR
No array in .NET can hold more than 2^31 element (
System.Int32.MaxValue
) or a max size of 2 GB which roughly would make for a 2 GB byte array.For a workaround see http://blogs.msdn.com/b/joshwil/archive/2005/08/10/450202.aspx
Another option is to use
MemoryMappedFile
and Streams on those - this will alow to access a file of any size...To make that download code work you could either read a chunk, send it, read the next chunk etc. OR use a
Stream
for reading and write to theOutputStream
without any intermediate buffer...Another option is to use
TransmitFile
which can handle files > 4 GB.EDIT - as per comment:
You could just replace the code after
with
OR with