如何在块中使用 File.ReadAllBytes

Posted

技术标签:

【中文标题】如何在块中使用 File.ReadAllBytes【英文标题】:How do I use File.ReadAllBytes In chunks 【发布时间】:2012-07-20 18:56:52 【问题描述】:

我正在使用此代码

        string location1 = textBox2.Text;
        byte[] bytes = File.ReadAllBytes(location1);
        string text = (Convert.ToBase64String(bytes));
        richTextBox1.Text = text;

但是当我使用太大的文件时,我会出现内存不足异常。

我想分块使用File.ReadAllBytes。我在下面看到过这样的代码

System.IO.FileStream fs = new System.IO.FileStream(textBox2.Text, System.IO.FileMode.Open);
byte[] buf = new byte[BUF_SIZE];
int bytesRead;

// Read the file one kilobyte at a time.
do

    bytesRead = fs.Read(buf, 0, BUF_SIZE);               
    // 'buf' contains the last 1024 bytes read of the file.

 while (bytesRead == BUF_SIZE);

fs.Close();


但我不知道如何实际将bytesRead 转换为我将转换为文本的字节数组。

编辑:找到答案。这是代码!

 private void button1_Click(object sender, EventArgs e)
    
        const int MAX_BUFFER = 2048;
        byte[] Buffer = new byte[MAX_BUFFER];
        int BytesRead;
        using (System.IO.FileStream fileStream = new FileStream(textBox2.Text, FileMode.Open, FileAccess.Read))
            while ((BytesRead = fileStream.Read(Buffer, 0, MAX_BUFFER)) != 0)
            
                string text = (Convert.ToBase64String(Buffer));
                textBox1.Text = text;

            


要更改文本格式的可读字节,请创建一个新字节并使其相等 (转换。FromBase64String(文本))。谢谢大家!

【问题讨论】:

【参考方案1】:

bytesRead 只是读取的字节数。

这里是一些块阅读

        var path = @"C:\Temp\file.blob";

        using (Stream f = new FileStream(path, FileMode.Open))
        
            int offset = 0;
            long len = f.Length;
            byte[] buffer = new byte[len];

            int readLen = 100; // using chunks of 100 for default

            while (offset != len)
            
                if (offset + readLen > len)
                
                    readLen = (int) len - offset;
                
                offset += f.Read(buffer, offset, readLen);
            
        

现在您有了buffer 中的字节,并且可以随意转换它们。

例如在“使用流”中:

            string result = string.Empty;

            foreach (byte b in buffer)
            
                result += Convert.ToChar(b);
            

【讨论】:

【参考方案2】:
private void button1_Click(object sender, EventArgs e)

    const int MAX_BUFFER = 2048;
    byte[] Buffer = new byte[MAX_BUFFER];
    int BytesRead;
    using (System.IO.FileStream fileStream = new FileStream(textBox2.Text, FileMode.Open, FileAccess.Read))
        while ((BytesRead = fileStream.Read(Buffer, 0, MAX_BUFFER)) != 0)
        
            string text = (Convert.ToBase64String(Buffer));
            textBox1.Text = text;

        

【讨论】:

【参考方案3】:

不,Read() 的返回值是读取了多少字节。数据位于您传递给Read() 的字节数组buf 中。您应该尝试理解代码,而不仅仅是复制和粘贴,然后询问为什么它不起作用。即使你这样做了,评论说出来就在那里!

【讨论】:

我试过了。你能帮我吗?如何将所有 buf 转换为一个大数组? 你为什么要这样做?这违背了大块阅读它的全部目的!这正是 ReadAllBytes 所做的 好的,我明白了,所以每次它以一个块的形式读取它,我将它转换为字符串并将其添加到文本框。喜欢哪部分代码 我不知道你到底想要完成什么!如果文件大于您拥有的内存量,您将耗尽内存。时期。你应该解释一下你想用这个程序做什么,然后我们也许可以给你一些有意义的建议。 好的,我想加载文件并获取字节,通过 Convert.ToBase64String 转换它们,然后将文本框的文本转换为转换后的字节。但是当我这样做并且文件太大(大约 100 兆)时,我会遇到内存不足的异常。因此,我想以块的形式加载数组,将每个块转换为 base 64 字符串并将其添加到文本框文本中。 @乔纳森·莱因哈特【参考方案4】:

根据文件结构,使用StreamReader 公开ReadLine 方法可能更容易。

using(var sr = new StreamReader(File.Open(textBox2.Text, FileMode.Open))

    while (sr.Peek() >= 0) 
    
        Console.WriteLine(sr.ReadLine());
     

【讨论】:

好的,我怎样才能将每个块添加到一个我将转换为字符串的数组中,而不是写行。或者将每个字节转换为字符串并添加到另一个字符串?【参考方案5】:

如果文件是文本文件,您可以使用 TextReader:

   string location1 = textBox2.Text;
    string text  = String.Empty;
    using (TextReader reader = File.OpenText(location1 ))
    
           do
           
           string line = reader.ReadLine();
               text+=line;
            
            while(line!=null)

    

【讨论】:

以上是关于如何在块中使用 File.ReadAllBytes的主要内容,如果未能解决你的问题,请参考以下文章

实现 API 时如何避免在块中捕获自我?

ALAssetLibraryGroup 在块中找到相机胶卷

有人可以解释 Ruby 在块中使用管道字符吗?

在块中复制和自动释放本地变量

无法在块中翻译 Django 模板

在块中返回非指针对象时出现问题