索引在 MSCORLIB.DLL 中的数组边界之外

Index was outside the bounds of the array in MSCORLIB.DLL

如果我找到解决方案,我会很惊讶,因为它非常具体和模糊,但我想我会尝试。我会尽量提供尽可能多的信息,因为我一直在寻找答案有一段时间了。

我正在用 C# 构建一个实用程序,它从 i-series/AS400 上的库中的文件中复制记录,并构建一个加密的文本文件,其中每条来自 AS400 的记录都是逗号分隔的字符串。在文件中,它将具有文件名、字段值 1、字段值 2、字段值 3 等值。然后我将该文本文件带到另一台 PC 上,然后 运行 一个 C# 实用程序将该记录复制到另一台 i 系列机器上的库中的相同文件名中。不幸的是,在某些情况下我会收到数组异常的外部边界,但我无法确定原因。在异常之前的记录中,记录看起来几乎相同并且工作正常。简而言之,我的代码如下。我通常不会放弃,但我不希望永远解决这个问题。如果有人愿意,我今晚可能会唱卡拉OK。

// Select records from AS400 file and write them to text file
Recordset rs = new Recordset();
sqlQuery = "SELECT * FROM " + dataLibrary + "." + fileName;

try
{
    rs.Open(sqlQuery, con);

    while (!rs.EOF)
    {
        int[] fieldLengths;
        fieldLengths = new int[rs.Fields.Count];
        String[] fieldValues;
        fieldValues = new String[rs.Fields.Count];
        String fullString = "";

        for (i = 0; i < rs.Fields.Count; i++)
        {
            fieldLengths[i] += rs.Fields[i].DefinedSize;
            fieldValues[i] += rs.Fields[i].Value;
        }

        fullString = fileName + "," + String.Join(",", fieldValues);
        fullString = Functions.EncryptString(fullString);

        File.AppendAllText(savefile.FileName, fullString + Environment.NewLine);
        rs.MoveNext();
    }
}
catch (Exception ex)
{
}

cmd.Dispose();
// This gives me a text file of filename, fieldvalue1, fieldvalue2, etc...
// Next, I take the file to another system and run this process:

while ((myString = inputFile.ReadLine()) != null)
{
    int stringLength = myString.Length;
    String[] valuesArray = myString.Split(',');

    for (i = 0; i < valuesArray.Length; i++)
    {
        if (i == 0)
        {
            fileName = valuesArray[0];
            // Create file if it doesn't exist already
            createPhysicalFile(newLibrary, fileName);
            SQLStatement = "INSERT INTO " + newLibrary + "." + fileName + "VALUES(";
        }
        else
        {
            if (i == valuesArray.Length - 1)
            {
                SQLStatement += "@VAL" + i + ")";
            }
            else
            {
                SQLStatement += "@VAL" + i + ", ";
            }
        }
    }

    try
    {
        using (connection)
        {
            try
            {
                connection.Open();
            }
            catch (Exception ex)
            {
            }

            // Create a new SQL command
            iDB2Command command = new iDB2Command(SQLStatement, connection);

            for (i = 1; i < valuesArray.Length; i++)
            {
                try
                {
                    command.Parameters.AddWithValue("@VAL" + i, (valuesArray[i]));
                }
                catch (Exception ex)
                {

                }
            }

            // Just split the array into a string to visually check 
            // differences in the records
            String arraySplit = ConvertStringArrayToString(valuesArray);

            // The query gets executed here.  The command looks something
            // like:  
            // INSERT INTO LIBNAME.FILENAME VALUES(@VAL!, @VAL2, @VAL3, @VAL4)
            // There are actually 320 fields in the file I'm having a problem with, 
            // so it's possible I'm overlooking something.  I have narrowed it down to 
            // field # 316 when the exception occurs, but in both cases 
            // field 316 is blanks (when it works and when it doesn't).
            command.ExecuteNonQuery();
        }
    }
    catch (Exception ex)
    {
        // Here I get the exception out of bounds error in MSCORLIB.DLL. 
        // Some records are added fine, while others cause this exception.
        // I cannot visibly tell any major differences, nor do I see any  
        // errors in the AS400 job log or anything in C# that would lead me 
        // down a certain path.
        String error = ex.Message;
    }
}

为了它的价值,我发现这种情况发生在系统中一个较小的文件中,并且在对代码和网络进行了艰苦的研究之后能够弄清楚发生了什么。基本上,文件文件在 i 系列上有数字字段。不知何故,记录被写入原始系统上的文件,其中数字字段中的值为空值而不是数值。在存储原始记录时,我不得不做这样的计算:

String fieldType = rs.Fields[i].Type.ToString();
object objValue = rs.Fields[i].Value;
if (fieldType == "adNumeric" && objValue is DBNull)
{
  fieldValues[i] += "0";
}
else
{
  fieldValues[i] += rs.Fields[i].Value;
}

在此之后,如果在其中一个数字字段中发现空值,它只会将“0”放入该位置,以便在写入新机器时,它会在其中放置一个有效的数字字符并继续写入其余值。感谢所有的建议和道义上的支持。 :)