当数据量可被1023或1024整除时,为什么获取操作会崩溃?

时间:2013-02-26 20:23:52

标签: c# io null windows-ce dispose

(或者,当被1023整除时(见下面的更新3))

我正在追逐当包含被提取数据的文件大小可以被1024整除时出现的错误。在这种情况下,提取似乎一直有效,直到完成,但最后会失败。< / p>

在这种情况下(当存在大小为1024的倍数的文件时)可能会发生奇怪的事情,我搜索了对#124; 1024&#34;在代码中,但没有专门提到的实时代码&#34; 1024。&#34;

我确实在提取代码中找到了一件我觉得很奇怪的东西,即:

connFrmSitesData.Dispose();
connFrmSitesData = null;

表单的此设置是否为null可能导致问题?它有什么理由在那里吗?

更新

我发现这个代码让我想知道:

string theMessage = new string( '\x00', 1023 );

......如果它可以切入问题。

更新2

现在我看到那个字符串(theMessage)*甚至没用过;我能够对它进行评论(在所有三个地方都有类似声明,之后没有使用过)。

为什么在这段代码中有:

bool    retVal      = false;            
string  theMessage  = new string( '\x00', 1023 ); // fill 1023 bytes with nulls
. . .
    if( retVal = Util.NetSendCommand( rc.command ) )

...是&#34; retVal&#34;已经变灰的变量(通过Resharper,我假设),而#34; theMessage&#34;是不是变灰了?

  • 还有一个&#34;正常&#34; ** theMessage声明为该类私有:

    私人字符串theMessage;

**&#34;正常&#34;因为它没有用重载的构造函数实例化。

更新3

我可能找到了问题区域(实际上是在一个不同的项目中 - 项目调用的.DLL)。

此代码可疑,因为MAXREAD = 1023。

任何人都可以看到有什么问题会导致精确大小的文件失败吗?例如,如果先前的Read已经获得了所有内容,那么对bReader.Read()的调用是否会失败?

或者在某处潜伏着其他问题?

BinaryReader bReader          = null;
. . .
bReader = new BinaryReader( theN_Stream );
. . .
fsWriteText = new FileStream( destFPath, FileMode.Create, FileAccess.Write );
. . .
bWriter = new BinaryWriter( fsWriteText );
. . .

/* --------------------------------------- *
 *   Incoming message may be larger than 
 *   the buffer size.
 * --------------------------------------- */ 
int index     = 0;
int indexLast = 0;
int next2Read = MAXREAD;

try
{
    // keep doing this until no data available on the stream, ...
    do
    {
        next2Read         = MAXREAD; //1023
        longString        = "";

    Array.Clear( readbuffer, 0, MAXREAD );

    numberOfBytesRead = bReader.Read( readbuffer, 0, next2Read );

    indexLast  = index;
    realTotBytesRead += numberOfBytesRead; 
    index     += numberOfBytesRead;
    nBytes    += numberOfBytesRead;
    xferProgress = nBytes.ToString() + "|" + fsize.ToString();
    OnProgressChanged(xferProgress);

    if( bWriter != null )
        {
            if( bWriter.BaseStream.CanWrite )
            {
                bWriter.Write( readbuffer, 0, numberOfBytesRead );
            }
        }

    if( index >= fsize )
    {
        haveFinishedRead = true;
        break;
    }

    if( !theN_Stream.CanRead )
    {
        break;
    }
} while( index < fsize );

更新4

在试图找到问题的根源时,我已经编译了(没有双关语)以下注释。

// readbuffer是一个字节数组。 // bReader是二进制阅读器

&#34;指数&#34;从0开始,分配读取的字节数(1023或余数/最后一位),稍后针对文件大小进行测试 - 如果等于或大于,则退出循环。

&#34; indexLast&#34;从0开始,首先分配索引的值(0第一次通过循环,然后是1023或余数/最后一位),但它永远不会被引用,所以它可以被注释掉。

&#34; next2Read&#34;最初是MAXREAD,即1023.它用于这一行:

numberOfBytesRead = bReader.Read( readbuffer, 0, next2Read );

...但之后没有引用,因此可以将其删除,并将上面的行更改为:

numberOfBytesRead = bReader.Read( readbuffer, 0, MAXREAD);

&#34; longString&#34;被初始化为空字符串,但随后没有被引用;但是,既然它是一个全局变量,那么其他地方可能需要这个值吗?

&#34; numberOfBytesRead&#34;被赋予bReader的Read()方法的返回值。然后将其分配给&#34; index&#34;和&#34; nBytes&#34;。然后将其用作&#34;要写入的字节数&#34;在调用bWriter.Write()时。

喜欢&#34; longString&#34;,&#34; realTotBytesRead&#34;在此方法中被赋值,然后未被引用,但由于它是全局变量,因此可以在其他地方使用...

&#34;为nbytes&#34;在&#34; numberOfBytesRead&#34;中分配值,然后用于进度条。似乎&#34; numberOfBytesRead&#34;可以用来削减中间人,但我想&#34; nBytes&#34;没有伤害任何东西(除了糊状的灰色东西,让我的头骨不会塌陷)...

&#34; FSIZE&#34;用于条件分支。它最初设置为0,然后以这种方式设置:

fsize = (int)Int32.Parse( fFileSz );

&#34; fFileSz&#34;是一个公共静态字符串,用于保存文件大小(在别处设置)。

&#34; theN_Stream&#34;是一个网络流。

在调试计算机程序时,你会成为一名侦探,但不是在黑暗的小巷中追逐坏人并暴露犯罪分子,而是在吸烟时表现得非常糟糕。这种侦探工作比另一种更安全 - 更久坐和更稳重 - 但是你在幸福的鞋子中获得并节省人寿保险费,你在破裂的突触和过度的脑细胞中失去了高空,WAY超越&#34;云&#34 ;;在你做过/不做的一切事情中总会做出权衡。

更新5

我现在期望问题出在其他地方,因为无论文件大小是否小于,等于或大于MAXREAD(1023),此代码似乎都有效。伪代码:

// filesize&lt; MAXREAD:

if filesize == 1022:
numberOfBytesRead == 1022
index == 1022;
//....breaks out (as it should, it's done), because index == fsize

// filesize == MAXREAD:// 1023

if filesize == 1023:
numberOfBytesRead == 1023
index == 1023;

//breaks out (as it should, it's done), because index == fsize

// filesize&gt; MAXREAD:

if filesize == 1024:
numberOfBytesRead == 1023
index == 1023;
...continues to loop again:
numberOfBytesRead == 1
index == 1024;
//breaks out (as it should, it's done), because index == fsize

//任何文件大小都应该相同&gt; MAXREAD

更新6

&#34;幻数&#34;已找到 - 当处理大小为190KB的文件时,应用程序崩溃。显示获取进程的进度条比冻结 - 永远和在每个实例中文件大小正是如此;否则它没问题(如果文件大小小于或大于190KB,它可以正常工作)。

更新7

我意识到这是一个糟糕的修复,但遗留代码是如此错综复杂,[故意?]混淆,并且是狡猾的 - 用DLL调用exe,反之亦然,多个背景线程触发和停止,像疯子般的掠夺灯一样闪烁和闪烁 - 我粗暴地强迫这种方式暂时修复,改变了这段代码:

if( processMessage )
{
                Util.ProcessServerResponse( theMessage.Trim( uDelims.ToCharArray() ) );
}

......对此:

if ( processMessage )
{
                string valToPass = theMessage.Trim(uDelims.ToCharArray());
                if (valToPass.IndexOf("190980") > 0)
                {
                                valToPass = valToPass.Replace("190980", "190978"); 
                }
                Util.ProcessServerResponse( valToPass );
}

//注意: 1)由于某种原因,当filesize是190980时,在DLL中发生无限循环,其中&#34;索引&#34; (已经读取的字节数)仍然小于表示要读取的总字节数的值 - 与所有其他字节,或者所有其他文件大小的百分比,它工作正常... 2)我无法使用string.Contains()来查找&#34; 190980&#34;只是因为它在.NET 1.1中不可用

0 个答案:

没有答案