簡體   English   中英

將大文件讀入字節數組並將其編碼為ToBase64String

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

我已經實現了POC將整個文件內容讀入Byte []數組。 我現在成功讀取大小低於100MB的文件,當我加載大小超過100MB的文件然后它正在拋出

Convert.ToBase64String(mybytearray)無法獲取局部變量或參數的值,因為沒有足夠的可用內存。

下面是我試圖從文件到字節數組讀取內容的代碼

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)中出現此錯誤。

有什么我需要注意防止這個錯誤?

注意:我不想在文件內容中添加換行符

為了節省內存,您可以轉換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,字節數組為133 MB,因為您寫的模型我希望這個133 MB的副本作為響應。 請記住,這只是一個簡單的請求。 一些這樣的請求可能會耗盡你的記憶。

我會使用兩個文件流 - 一個用於讀取大文件,一個用於將結果寫回。

所以在塊中你會轉換為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