(或者,当被1023整除时(见下面的更新3))
我正在追逐当包含被提取数据的文件大小可以被1024整除时出现的错误。在这种情况下,提取似乎一直有效,直到完成,但最后会失败。< / p>
在这种情况下(当存在大小为1024的倍数的文件时)可能会发生奇怪的事情,我搜索了对#124; 1024&#34;在代码中,但没有专门提到的实时代码&#34; 1024。&#34;
我确实在提取代码中找到了一件我觉得很奇怪的东西,即:
connFrmSitesData.Dispose();
connFrmSitesData = null;
表单的此设置是否为null可能导致问题?它有什么理由在那里吗?
我发现这个代码让我想知道:
string theMessage = new string( '\x00', 1023 );
......如果它可以切入问题。
现在我看到那个字符串(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;因为它没有用重载的构造函数实例化。
我可能找到了问题区域(实际上是在一个不同的项目中 - 项目调用的.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 );
在试图找到问题的根源时,我已经编译了(没有双关语)以下注释。
// 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 ;;在你做过/不做的一切事情中总会做出权衡。
我现在期望问题出在其他地方,因为无论文件大小是否小于,等于或大于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
&#34;幻数&#34;已找到 - 当处理大小为190KB的文件时,应用程序崩溃。显示获取进程的进度条比冻结 - 永远和在每个实例中文件大小正是如此;否则它没问题(如果文件大小小于或大于190KB,它可以正常工作)。
我意识到这是一个糟糕的修复,但遗留代码是如此错综复杂,[故意?]混淆,并且是狡猾的 - 用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中不可用