繁体   English   中英

算术运算导致溢出错误-对于c#中的byte []数组

[英]Arithmetic operation resulted in an overflow ERROR - for byte[] arrays in c#

我在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;
            }
        }
    }
}

提前致谢

.NET中的任何数组都不能容纳超过2 ^ 31个元素( System.Int32.MaxValue )或2 GB的最大大小,这大约可以构成2 GB的字节数组。

有关解决方法,请参见http://blogs.msdn.com/b/joshwil/archive/2005/08/10/450202.aspx

另一个选择是在这些文件上使用MemoryMappedFileStreams-这将允许访问任何大小的文件...

为了让这个下载代码的工作,你既可以读一大块,发送,阅读下一大块等,或使用Stream读取和写入OutputStream没有任何中间缓冲...

另一种选择是使用TransmitFile ,它可以处理大于4 GB的文件。

编辑-根据评论:

您可以在之后替换代码

if (filePath == null)
{
return;
}

response.Clear();

response.ContentType = GetMimeType (System.IO.Path.GetFileName(filePath));

response.AddHeader("content-disposition", "attachment; filename=" + System.IO.Path.GetFileName(filePath));

response.TransmitFile (filePath);    

long FileL = (new FileInfo(filePath)).Length;
byte[] bytes = new byte[1024*1024];

response.Clear();

response.ContentType = GetMimeType (System.IO.Path.GetFileName(filePath));

response.AddHeader("content-disposition", "attachment; filename=" + System.IO.Path.GetFileName(filePath));

response.AddHeader("Content-Length", FileL.ToString());

using (FileStream FS = File.OpenRead(filePath))
{
int bytesRead = 0;
while ((bytesRead = FS.Read (bytes, 0, bytes.Length)) > 0 )
{
response.OutputStream.Write(bytes, 0, bytesRead);
response.Flush();
};

response.Close();
}

您将不得不使用较小的缓冲区并逐个读取流。 我认为您将无法创建大于4 GB的字节数组。

如果使用的是.NET 4,则可以使用新的Stream.CopyTo(Stream)实例方法将输入流复制到输出流。

在.NET中,您可以分配的最大对象约为2GB。 文档引用:

与32位Windows操作系统一样,在64位Windows操作系统上运行64位托管应用程序时,可以创建的对象大小限制为2GB。

还有CLR团队的博客文章

当然2GB是理论上的限制。 实际极限较低。 因此,您将必须阅读以下内容:

const int ChunkSize = 1024 * 1024 * 4; // process in chunks of 4MB:
using (var br = new BinaryReader(streamReader.BaseStream))
{
    var buffer = new byte[ChunkSize];
    int bytesRead;
    while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)
    {
        // TODO: process the chunk which is the buffer array from 0 to bytesRead
    }
}

而且您的代码似乎有点奇怪。 您有一个StreamReader,它处理编码的字符串,但是您正在使用字节数组和BinaryReaders。 似乎有点奇怪。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM