【问题标题】:Buffer.BlockCopy does not work more than one timeBuffer.BlockCopy 不工作超过一次
【发布时间】:2015-09-08 07:43:58
【问题描述】:

我有一个类,它每次接收缓冲区时都应该附加到更大的字节数组,但它只在第一次进行块复制,然后它不会复制任何东西
缓冲区第一次进入类时,它会复制 allData 中的内容。但是第二次它全为零,尽管缓冲区包含数据。 这是我的代码:

public Boolean WriteBlobsToDB(byte[] buffer, int offset, int fileSize, string fileName, string fileType, string user, int count, int NChunks, string md5Src,int id)
{
    bool ret = false;
    int l = buffer.Length; // The buffer length is almost 2 MB
    var allData = new byte[fileSize];
    int offst = count * offset; // count is 0 the first timethen each time a new buffer comes, the value of count in count++ 

    Buffer.BlockCopy(buffer, 0, allData, offst, fileSize);
    if (count == NChunks-1 ) // NChunks is the number of how many time the buffer would be passed here 
    {               // the meaning of this if is that, when all the buffer of a file is passed then move to the database and upload the table
        File_List fl = new File_List();
        fl.FileName = fileName;
        fl.Id = id;
        fl.FileType = fileType;
        fl.MD5 = md5Src;
        fl.Data = new Binary(allData);
        try
        {
            dc.SubmitChanges();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

    }

    return ret;
}

【问题讨论】:

  • 我在这里看不到任何循环
  • 没有循环,这是每次收到块时从处理程序调用的类
  • 输入输出是什么?您正在将数据复制到名为“allData”的局部变量中。
  • 变量“fl”未在任何地方定义。那个“wfl”是错字吗?
  • 我向你保证:Buffer.BlockCopy 工作得很好。问题在于您如何使用它,但我们没有足够的上下文来正确评估它;一个简单的可重现示例会很棒,但是:不是这样。

标签: c# sql arrays buffer varbinary


【解决方案1】:
var allData = new byte[fileSize];
int offst = count * offset;
Buffer.BlockCopy(buffer, 0, allData, offst, fileSize);

这里,allData 的长度为 fileSize。当count0(第一次)时,您说它有效;那么,让我们考虑count 非零的情况。您告诉它从buffer 复制fileSize 字节到allData,从buffer 中的偏移量0 开始读取,并从allData 中的偏移量offset 开始写入。我们知道当count 非零时,offst 非零。由于allDatafileSize 字节长,这将总是溢出边界(写入位置的末尾将是fileSize+offstoffst 非零且数组长度fileSize)。我希望它会提出一个您没有告诉我们的ArgumentOutOfRangeException

编辑:实际上,它是一个ArgumentException

System.ArgumentException: 数组的偏移量和长度超出范围,或者计数大于从索引到源集合末尾的元素数。

基本上:要么你的参数设置错误,要么你告诉它做一些永远不会工作的事情。

您有可能(可能?):

Buffer.BlockCopy(buffer, offst, allData, 0, fileSize);

【讨论】:

  • filesize 只是变量的名称。我们不确定如何使用该变量。例如,我认为 OP 将其用作长度。我同意你的看法,我们没有多少信息可以回答这个问题。
  • @sam 是的;除了代码中存在的含义外,我没有读到它的任何含义。如果您创建一个长度为fileSize 的数组,并尝试将fileSize 字节写入其中从非零偏移量开始,事情就不会顺利进行。不管fileSize 是什么意思,这句话都是真的。
  • 这就是故事。每次我收到作为文件一部分的块时,在我的处理程序上。在这里,我想将所有接收到的块(我称之为 byte[] 类型的缓冲区)附加到一个与我的文件大小相同的字节数组中。每次缓冲区大小为 2 MB。所以我有缓冲区,当你总结它们的大小时,它们的大小将等于文件大小。
  • @laila 不会改变所写代码的逻辑;基本上你是在说:“创建一个长度为 10 的数组,现在从 5 开始向其中写入 10 个值,所以位置... 5-14” - 没有 位置 10-14。另请注意,您的代码没有 附加 任何内容;它是将一个大缓冲区拆分成多个片段。
  • @laila 作为旁注:除非它是最后一个片段,否则数据实际上无论如何都会被丢弃
【解决方案2】:

您在buffer[] 中收到一大块字节,并将其复制到一个局部变量中。 您正在复制一个名为 allData 的局部变量中的字节,该变量每次都是新创建的。

您也应该将接收器缓冲区allData 传递给函数。

【讨论】:

  • allData 是方法的本地可能是完全有效和正确的,特别是因为它在 Binary 的构造函数中使用 - 对于独立的那些将是正确的。对不起,但我认为这不是一个有用的答案。为你辩护:这个问题没有提供足够的信息一个有用的答案,IMO。
  • @MarcGravell 好吧,莱拉说这个函数是在其他地方的循环中调用的,所以整个缓冲区是一个本地变量,因此每次循环迭代都重新创建对我来说确实很狡猾。
  • 但即使是每次初始化的问题(allData)bt,它也应该复制daya。但它没有,我也更新解释更多
  • 我希望不会在本地重新创建名为 alldata 的变量。
  • @sam 只要allData指的是“构成我们称为fileName的逻辑文件的所有数据”,那么它不是一个不合理的名称; fileContents 可能会更好,但是……嗯
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多