C#Winforms IO错误 [英] C# Winforms IO Errors
问题描述
我遇到了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 theparseCSV
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 $ c $的方式c>方法有效。使用当前代码,它将返回
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.
如果我没弄错的话,你将2228个字段/列写入CSV文件,但是当您阅读时,您希望在从CSV解析的数组中找到29个元素。所以你写的列数太少或读得太多。
If I'm not mistaken, you write2228 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屋!