【问题标题】:Can't read FileStream into byte[] correctly无法正确将 FileStream 读入 byte[]
【发布时间】:2014-12-28 21:55:31
【问题描述】:

我有一些 C# 代码要调用为 TF(true,"C:\input.txt","C:\noexistsyet.file"),但是当我运行它时,它会在 FileStream.Read() 上中断,因为它会将文件的最后一块读入缓冲区,得到一个索引越界 @987654323 @。

对我来说,代码似乎合乎逻辑,尝试写入缓冲区时没有溢出。我以为我已经用rdlen_chunk 进行了所有设置,但也许我看错了。有什么帮助吗?

我的错误:ArgumentException was unhandled: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.

public static bool TF(bool tf, string filepath, string output)
    {
        long _chunk = 16 * 1024; //buffer count
        long total_size = 0
        long rdlen = 0;
        long wrlen = 0;
        long full_chunks = 0;
        long end_remain_buf_len = 0;
        FileInfo fi = new FileInfo(filepath);
        total_size = fi.Length;
        full_chunks = total_size / _chunk;
        end_remain_buf_len = total_size % _chunk;
        fi = null;
        FileStream fs = new FileStream(filepath, FileMode.Open);
        FileStream fw = new FileStream(output, FileMode.Create);
        for (long chunk_pass = 0; chunk_pass < full_chunks; chunk_pass++)
        {
            int chunk = (int)_chunk * ((tf) ? (1 / 3) : 3); //buffer count for xbuffer
            byte[] buffer = new byte[_chunk];
            byte[] xbuffer = new byte[(buffer.Length * ((tf) ? (1 / 3) : 3))];
            //Read chunk of file into buffer
            fs.Read(buffer, (int)rdlen, (int)_chunk); //ERROR occurs here
            //xbuffer = do stuff to make it *3 longer or *(1/3) shorter;
            //Write xbuffer into chunk of completed file
            fw.Write(xbuffer, (int)wrlen, chunk);
            //Keep track of location in file, for index/offset
            rdlen += _chunk;
            wrlen += chunk;
        }
        if (end_remain_buf_len > 0)
        {
                byte[] buffer = new byte[end_remain_buf_len];
                byte[] xbuffer = new byte[(buffer.Length * ((tf) ? (1 / 3) : 3))];
                fs.Read(buffer, (int)rdlen, (int)end_remain_buf_len); //error here too
                //xbuffer = do stuff to make it *3 longer or *(1/3) shorter;
                fw.Write(xbuffer, (int)wrlen, (int)end_remain_buf_len * ((tf) ? (1 / 3) : 3));
                rdlen += end_remain_buf_len;
                wrlen += chunk;
        }
        //Close opened files
        fs.Close();
        fw.Close();
        return false; //no functionality yet lol
    }

【问题讨论】:

  • Stream.Copy 或 File.Copy 怎么样?
  • 学会爱using blocks。
  • 您应该重新考虑方法/参数名称TF/tf。谁会tf false 打电话给TF
  • @C.Evenhuis:代码就是一个例子。我保存的文件实际上并没有使用 TF(,,*) 调用,我只是将 TF 放在那里作为示例。与非功能返回 false/true 相同; @BenVoigt:我在下面看到了有用的代码using,这可能是我的代码的第 5 次或第 6 次重写,因为我在代码中的其他文件不同时使用了 using。并且@usr 复制功能我相信有自己的块大小,但我相信这对我来说并不重要,如果我需要,我将不得不考虑合并这些功能谢谢大家!

标签: c# arrays io byte filestream


【解决方案1】:

StreamFileStream 的基类)的Read() 方法返回一个int,表示读取的字节数,0 表示没有更多字节要读取,所以你甚至不用需要事先知道文件大小:

public static void CopyFileChunked(int chunkSize, string filepath, string output)
{
    byte[] chunk = new byte[chunkSize];

    using (FileStream reader = new FileStream(filepath, FileMode.Open))
    using (FileStream writer = new FileStream(output, FileMode.Create))
    {
        int bytes;
        while ((bytes = reader.Read(chunk , 0, chunkSize)) > 0)
        {
            writer.Write(chunk, 0, bytes);
        }
    }
}

甚至File.Copy() 也可以解决问题,如果您可以让框架决定块大小。

【讨论】:

  • 这真是太棒了!谢谢你的帮助!在第一次尝试时将这部分代码完美地合并到我的代码中;)
【解决方案2】:

我认为它在这条线上失败了:

  fw.Write(xbuffer, (int)wrlen, chunk);

您将 xbuffer 声明为

 byte[] xbuffer = new byte[(buffer.Length * ((tf) ? (1 / 3) : 3))];

由于1 / 3 是一个整数除法,它返回0。并且您声明xbuffer 的大小为0,因此错误。您可以通过将操作数之一转换为浮点类型或使用文字来修复它。但是你仍然需要将结果转换回整数。

 byte[] xbuffer = new byte[(int)(buffer.Length * ((tf) ? (1m / 3) : 3))];

chunk 声明中也存在同样的问题。

【讨论】:

  • 我最终选择了(tf) ? (Length / 3) : (Length * 3)) 来解决使用 (1/3) 获取 .333 时的 int/float 问题,因为我知道 Length 将是3 或乘以 3,具体取决于 tf 是真还是假;谢谢!
猜你喜欢
  • 2019-07-27
  • 1970-01-01
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多