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

时间:2018-09-10 14:27:19

标签: c# base64 filereader

我已经实现了POC来将整个文件内容读入Byte []数组。现在,当加载的文件大小超过100MB时,我成功读取了大小小于100MB的文件

  

Convert.ToBase64String(mybytearray)无法获取   局部变量或参数,因为没有足够的内存   可用。

下面是我的代码,我试图将文件中的内容读取到Byte数组

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

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

我的模型课如下

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

我收到“ Convert.ToBase64String(mybytearray)无法获得局部变量或参数的值,因为没有足够的可用内存。”在Convert.ToBase64String(mybytearray)出现此错误。

我有什么需要注意的以防止出现此错误?

注意:我不想在文件内容中添加换行符

2 个答案:

答案 0 :(得分:2)

要节省内存,您可以将字节流转换为3个数据包。每三个字节在Base64中产生4个字节。您不需要一次存储整个文件。

这是伪代码:

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

简单的实现方式

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);
    }
}

提示:每乘以3是有效的。更高-更大的内存,更好的性能,更低-更少的内存,更差的性能。

其他信息:

文件流就是一个例子。结果,流使用[HttpContext].Response.OutputStream并直接写入。在一块中处理数百兆字节将杀死您和您的服务器。

考虑总内存需求。 100MB的字符串,导致133MB的字节数组,因为您撰写了有关模型的文章,因此我希望获得133MB的副本。记住,这只是一个简单的请求。一些这样的请求可能会耗尽您的内存。

答案 1 :(得分:0)

我将使用两个文件流-一个用于读取大文件,一个用于将结果写回。

因此,您将以大块形式转换为以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();
            }
        }
    }