简体   繁体   English

将大文件读入字节数组并将其编码为ToBase64String

[英]Read large file into byte array and encode it to ToBase64String

I have implemented POC to read entire file content into Byte[] array. 我已经实现了POC将整个文件内容读入Byte []数组。 I am now succeeded to read files whose size below 100MB, when I load file whose size more than 100MB then it is throwing 我现在成功读取大小低于100MB的文件,当我加载大小超过100MB的文件然后它正在抛出

Convert.ToBase64String(mybytearray) Cannot obtain value of the local variable or argument because there is not enough memory available. Convert.ToBase64String(mybytearray)无法获取局部变量或参数的值,因为没有足够的可用内存。

Below is my code that I have tried to read content from file to Byte array 下面是我试图从文件到字节数组读取内容的代码

var sFile = fileName;
var mybytearray = File.ReadAllBytes(sFile);

var binaryModel = new BinaryModel
{
    fileName = binaryFile.FileName,
    binaryData = Convert.ToBase64String(mybytearray),
    filePath = string.Empty
};

My model class is as below 我的模型类如下

public class BinaryModel
{
    public string fileName { get; set; }
    public string binaryData { get; set; }
    public string filePath { get; set; }
}

I am getting "Convert.ToBase64String(mybytearray) Cannot obtain value of the local variable or argument because there is not enough memory available." 我得到“Convert.ToBase64String(mybytearray)无法获取局部变量或参数的值,因为没有足够的可用内存。” this error at Convert.ToBase64String(mybytearray). Convert.ToBase64String(mybytearray)中出现此错误。

Is there anything which I need to take care to prevent this error? 有什么我需要注意防止这个错误?

Note: I do not want to add line breaks to my file content 注意:我不想在文件内容中添加换行符

To save memory you can convert stream of bytes in 3-packs. 为了节省内存,您可以转换3个包中的字节流。 Every three bytes produce 4 bytes in Base64. 每三个字节在Base64中产生4个字节。 You don't need whole file in memory at once. 您不需要立即在内存中存储整个文件。

Here is pseudocode: 这是伪代码:

Repeat
1. Try to read max 3 bytes from stream
2. Convert to base64, write to output stream

And simple implementation: 简单的实现:

using (var inStream = File.OpenRead("E:\\Temp\\File.xml"))
using (var outStream = File.CreateText("E:\\Temp\\File.base64"))
{
    var buffer = new byte[3];
    int read;
    while ((read = inStream.Read(buffer, 0, 3)) > 0)
    {
        var base64 = Convert.ToBase64String(buffer, 0, read);
        outStream.Write(base64);
    }
}

Hint: every multiply of 3 is valid. 提示:每次乘以3都是有效的。 Higher - more memory, better performance, lower - less memory, worse performance. 更高 - 更多的内存,更好的性能,更低的内存,更差的性能。

Additional info: 附加信息:

File stream is an example. 文件流就是一个例子。 As a result stream use [HttpContext].Response.OutputStream and write directly to it. 结果流使用[HttpContext].Response.OutputStream并直接写入它。 Processing hundreds of megabytes in one chunk will kill you and your server. 在一个块中处理数百兆字节将会扼杀您和您的服务器。

Think about total memory requirements. 考虑总内存需求。 100MB in string, leads to 133 MB in byte array, since you wrote about model I expect copy of this 133 MB in response. 字符串为100MB,字节数组为133 MB,因为您写的模型我希望这个133 MB的副本作为响应。 And remember it's just a simple request. 请记住,这只是一个简单的请求。 A few such requests could drain your memory. 一些这样的请求可能会耗尽你的记忆。

I would use two filestreams - one to read the large file, one to write the result back out. 我会使用两个文件流 - 一个用于读取大文件,一个用于将结果写回。

So in chunks you would convert to base 64 ... then convert the resulting string to bytes ... and write. 所以在块中你会转换为base 64 ...然后将结果字符串转换为字节...并写入。

    private static void ConvertLargeFileToBase64()
    {
        var buffer = new byte[16 * 1024];
        using (var fsIn = new FileStream("D:\\in.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (var fsOut = new FileStream("D:\\out.txt", FileMode.CreateNew, FileAccess.Write))
            {
                int read;
                while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0)
                {
                    // convert to base 64 and convert to bytes for writing back to file
                    var b64 = Encoding.ASCII.GetBytes(Convert.ToBase64String(buffer));

                    // write to the output filestream
                    fsOut.Write(b64, 0, read);
                }

                fsOut.Close();
            }
        }
    }

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

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