C#Winforms IO错误 [英] C# Winforms IO Errors

查看:81
本文介绍了C#Winforms IO错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了C#Winforms文件IO的问题。代码符合要求,但是它会在执行时返回错误。



输出代码在这里:



I'm having issues with a C# Winforms file IO. The code complies just fine, but then it returns errors on execution.

The output code is here:

private void saveData()
       {
           string fullPath = System.Environment.GetEnvironmentVariable(@"%MyDocuments%\HellsingRPG\");

           StreamWriter writer = new StreamWriter(fullPath + textBox2.Text + ".txt");
           writer.WriteLine(textBox1.Text + "," + textBox2.Text + "," + textBox3.Text + "," + textBox4.Text + "," + comboBox1.SelectedText + "," +
               numericUpDown25.Value + "," + numericUpDown1.Value + "," + numericUpDown2.Value + "," + numericUpDown3.Value + "," + numericUpDown4.Value + "," +
               numericUpDown5.Value + "," + numericUpDown6.Value + "," + numericUpDown7.Value + "," + numericUpDown8.Value + "," + numericUpDown9.Value + "," +
               numericUpDown10.Value + "," + numericUpDown11.Value + "," + numericUpDown12.Value + "," + numericUpDown13.Value + "," + numericUpDown14.Value
               + "," + numericUpDown15.Value + "," + numericUpDown16.Value + "," + numericUpDown17.Value + "," + numericUpDown18.Value + "," +
               numericUpDown19.Value + "," + numericUpDown20.Value + "," + numericUpDown21.Value + "," + numericUpDown22.Value);
           writer.Close();
       }





加载数据的代码如下:





And the code to load the data is here:

private void loadData()
       {
           Stream myStream = null;
           OpenFileDialog openFileDialog1 = new OpenFileDialog();

           openFileDialog1.InitialDirectory = System.Environment.GetEnvironmentVariable(@"%MyDocuments%\HellsingRPG\");
           openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
           openFileDialog1.FilterIndex = 2;
           openFileDialog1.RestoreDirectory = true;

           if (openFileDialog1.ShowDialog() == DialogResult.OK)
           {
               try
               {
                   if ((myStream = openFileDialog1.OpenFile()) != null)
                   {
                       using (myStream)
                       {
                           List<string> myData = parseCSV(System.Convert.ToString(myStream));
                           textBox1.Text = myData[0];
                           textBox2.Text = myData[1];  // here is the mistake
                           textBox3.Text = myData[3];   // <-----
                           textBox4.Text = myData[4];
                           comboBox1.SelectedText = myData[5];
                           numericUpDown25.Value = System.Convert.ToDecimal(myData[6]);
                           numericUpDown1.Value = System.Convert.ToDecimal(myData[7]);
                           numericUpDown2.Value = System.Convert.ToDecimal(myData[8]);
                           numericUpDown3.Value = System.Convert.ToDecimal(myData[9]);
                           numericUpDown4.Value = System.Convert.ToDecimal(myData[10]);
                           numericUpDown5.Value = System.Convert.ToDecimal(myData[11]);
                           numericUpDown6.Value = System.Convert.ToDecimal(myData[12]);
                           numericUpDown7.Value = System.Convert.ToDecimal(myData[13]);
                           numericUpDown8.Value = System.Convert.ToDecimal(myData[14]);
                           numericUpDown9.Value = System.Convert.ToDecimal(myData[15]);
                           numericUpDown10.Value = System.Convert.ToDecimal(myData[16]);
                           numericUpDown11.Value = System.Convert.ToDecimal(myData[17]);
                           numericUpDown12.Value = System.Convert.ToDecimal(myData[18]);
                           numericUpDown13.Value = System.Convert.ToDecimal(myData[19]);
                           numericUpDown14.Value = System.Convert.ToDecimal(myData[20]);
                           numericUpDown15.Value = System.Convert.ToDecimal(myData[21]);
                           numericUpDown16.Value = System.Convert.ToDecimal(myData[22]);
                           numericUpDown17.Value = System.Convert.ToDecimal(myData[23]);
                           numericUpDown18.Value = System.Convert.ToDecimal(myData[24]);
                           numericUpDown19.Value = System.Convert.ToDecimal(myData[25]);
                           numericUpDown20.Value = System.Convert.ToDecimal(myData[26]);
                           numericUpDown21.Value = System.Convert.ToDecimal(myData[27]);
                           numericUpDown22.Value = System.Convert.ToDecimal(myData[28]);
                       }
                   }
               }
               catch (Exception ex)
               {
                   MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
               }
           }
       }





解析代码在这里:< br $>




And the parsing code is here:

public System.Collections.Generic.List<string> parseCSV(string path)
        {
            System.Collections.Generic.List<string> parsedData = new System.Collections.Generic.List<string>();

            try
            {
                using (StreamReader readFile = new StreamReader(path))
                {
                    string line;
                    string[] row;

                    while ((line = readFile.ReadLine()) != null)
                    {
                        row = line.Split(',');
                        parsedData.Add(System.Convert.ToString(row));
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return parsedData;
        }





编译得很好。它作为可执行文件运行。我可以保存文件而不会发生意外。但是当我打开刚保存的文件时,我收到以下错误:



无法找到文件C:\ Users \collmark \Documents \\ \\ Visual Studio 2015 \Projects\WindowsFormsApplication1 \ WindowsFormsApplication1 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\来自磁盘的文件。原始错误:索引超出范围。必须是非负数且小于集合的大小。参数名称:索引。



任何想法我可能做错了什么?我是一个新的/自学c#用户。



And that compiles just fine. It runs as an executable. I can save the file without incident. But when I open the file I just saved, I get the following errors:

"Could not find file "C:\Users\collmark\Documents\Visual Studio 2015\Projects\WindowsFormsApplication1\WindowsFormsApplication1\bin\Release\System.IO.Filestream".

"Error: Could not read file from disk. Original error: Index out of range. Must be non-negative and less than the size of the collection. Parameter name: index."

Any ideas what I could be doing wrong? I'm a new/self taught c# users.

推荐答案

问题是你传递给 parseCSV 方法的路径:

The problem is the path you're passing to the parseCSV method:
parseCSV(System.Convert.ToString(myStream))



Convert.ToString 将调用<$ c您传入的对象上的$ c> ToString 方法。由于 Stream 未覆盖该方法,因此将调用 ToString 对象类上定义的方法,它只返回类型名称 - System.IO.FileStream



然后将该字符串传递给 StreamReader 构造函数,该构造函数需要一个文件路径由于它不是一个完全限定的文件路径,因此您传入的字符串将与当前工作目录相结合 - C:\ Users \ collmark \Documents\Visual Studio 2015 \Projects \ WindowsWindowsFormsApplication1 \WindowsFormsApplication1 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\路径中的文件 C:\Users\collmark \Documents\Visual Studio 2015 \Projects\WindowsFormsApplication1 \WindowsFormsApplication1 \bin\Release\System.IO.FileStream ,然后你得到一个 FileNotFoundException



你应该传递 Stream parseCSV 方法,并将其传递给 StreamReader 构造函数,该构造函数接受 Stream 参数。



您还需要更改 parseCSV 方法有效。使用当前代码,它将返回 string 值的列表,每行一个文件,其中每个字符串都是System.String [ ]。相反,你需要返回一个字符串数组列表,其中每个数组代表一行,数组的元素代表值。



这样的东西:


Convert.ToString will call the ToString method on the object you passed in. Since Stream doesn't override that method, this will call the ToString method defined on the object class, which simply returns the type name - System.IO.FileStream.

You then pass that string to the StreamReader constructor, which is expecting a file path. Since it's not a fully qualified file path, the string you've passed in will be combined with the current working directory - C:\Users\collmark\Documents\Visual Studio 2015\Projects\WindowsFormsApplication1\WindowsFormsApplication1\bin\Release\ - to create the full path of the file to open.

Since there isn't a file in the path C:\Users\collmark\Documents\Visual Studio 2015\Projects\WindowsFormsApplication1\WindowsFormsApplication1\bin\Release\System.IO.FileStream, you then get a FileNotFoundException.

You should pass the Stream to the parseCSV method, and pass that on to the StreamReader constructor which accepts a Stream argument.

You'll also need to change how the parseCSV method works. With the current code, it would return a list of string values, one per row of the file, where each string would be "System.String[]". Instead, you need to return a list of string arrays, where each array represents a single row, and the elements of the array represent the values.

Something like this:

public List<string[]> parseCSV(Stream fileStream)
{
    using (StreamReader readFile = new StreamReader(fileStream))
    {
        List<string[]> parsedData = new List<string[]>();

        string line;
        string[] row;
        while ((line = readFile.ReadLine()) != null)
        {
            row = line.Split(',');
            parsedData.Add(row);
        }

        return row;
    }
}

private void loadData()
{
    OpenFileDialog openFileDialog1 = new OpenFileDialog();
    openFileDialog1.InitialDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "HellsingRPG");
    openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
    openFileDialog1.FilterIndex = 2;
    openFileDialog1.RestoreDirectory = true;
    
    if (openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        try
        {
            using (Stream myStream = openFileDialog1.OpenFile())
            {
                if (myStream != null)
                {
                    List<string[]> myData = parseCSV(myStream);
                    if (myData.Count != 0)
                    {
                        string[] firstRow = myData[0];
                        if (firstRow.Length >= 29)
                        {
                            textBox1.Text = myData[0];
                            ...
                            numericUpDown22.Value = Convert.ToDecimal(myData[28]);
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.ToString());
        }
    }
}





注意: Environment.GetEnvironmentVariable(@%MyDocuments%\HellsingRPG \)将始终返回 null ,因为没有环境变量用这个名字。使用 ExpandEnvironmentVariables 方法,或 Environment.GetFolderPath Path.Combine的组合方法。



NB 2: Convert.ToDecimal 如果从文件读取的值不是有效数字,则行将失败。您应该考虑使用 小数.TryParse 方法 [ ^ ]。



NB 3:虽然这个简单的解析器应该使用您创建的文件,真正的CSV文件可能要复杂得多。例如,字段值可以包含逗号,引号和换行符。有许多现成的库可以为您处理 - 例如, CsvHelper [ ^ ]。



NB: Environment.GetEnvironmentVariable(@"%MyDocuments%\HellsingRPG\") will always return null, as there is no environment variable with that name. Either use the ExpandEnvironmentVariables method, or a combination of the Environment.GetFolderPath and Path.Combine methods.

NB 2: The Convert.ToDecimal lines will fail if the value read from the file isn't a valid number. You should consider using the decimal.TryParse method[^] instead.

NB 3: Whilst this simple parser should work with the file that you've created, real CSV files can be much more complicated. For example, field values can contain commas, quotes, and new-lines. There are lots of ready-made libraries to handle this for you - for example, CsvHelper[^].


parseCSV(System。 Convert.ToString(myStream))



我认为你不想把你的Stream变成一个字符串。





你肯定需要学习不使用转换。
parseCSV(System.Convert.ToString(myStream))

I don't think you want to be turning your Stream into a String.


And you definitely need to learn not to use Convert.


如果我没弄错的话,你将 22 28个字段/列写入CSV文件,但是当您阅读时,您希望在从CSV解析的数组中找到29个元素。所以你写的列数太少或读得太多。
If I'm not mistaken, you write 22 28 fields/columns to the CSV file but when you read, you expect to find 29 elements in the array parsed from the CSV. SO either you write too few columns or read too many.


这篇关于C#Winforms IO错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆