以不同的方法读取相同的文本文件
Read Same Text File in Different Methods
在 BtnNext_Click
方法中,它只是从文本文件中读取,就像它是另一个文本文件一样,而不是从已经打开的文件中读取。它不会从一行到另一行。
我需要帮助
代码如下:
public void ScrubData()
{
string FileName1;
string FilePath1;
// Display an OpenFile Dialog box for user
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "txt Files|*.txt";
openFileDialog1.Title = "Select a txt File";
// Show the Dialog. If user clicked OK in the dialog
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
try
{
String strFileName = openFileDialog1.FileName;
String strFilePath = System.IO.Path.GetDirectoryName(strFileName);
String fileName = System.IO.Path.GetFileNameWithoutExtension(strFileName);
String strFileNameAndPathNew = strFilePath +
openFileDialog1.InitialDirectory + "\" + fileName + "_scrubbed.txt";
// If scrubbed file exists, delete it first
if (System.IO.File.Exists(strFileNameAndPathNew))
{
System.IO.File.Delete(strFileNameAndPathNew);
} // End IF
if (System.IO.File.Exists(strFileName))
{
int lineCount = System.IO.File.ReadAllLines(strFileName).Length;
System.IO.StreamReader file = new System.IO.StreamReader(strFileName);
// Status label
LblStatus.Text = "File Loaded Successfully";
LblStatus.Visible = true;
string line;
while ((line = file.ReadLine()) != null)
{
const char DELIM = '|';
// MessageBox.Show(line);
string[] word = line.Split(DELIM);
Txt2NormAccNum.Text = word[3];
//string accScrubbed = ReplaceData(word[0],"SSN");
Txt3NormAmnt.Text = word[4];
Txt4NormFirstNam.Text = word[1];
Txt5NormLastNam.Text = word[2];
Txt6NormSS.Text = word[0];
Txt7NormItem.Text = word[5];
} // End WHILE
} // End IF
else
{
// Status label
LblStatus.Text = "File Load Failed!";
LblStatus.Visible = true;
} // End ELSE
// Text box one code:
FileName1 = openFileDialog1.FileName;
Txt1.Text = FileName1;
//
} // End TRY
catch (Exception e1)
{
if (e1.Source != null)
{
Console.WriteLine("IOException source: {0}", e1.Source);
throw;
} // End IF
} // End CATCH
} // End IF
} // End Scrub Method
我需要在下一个方法中重用 "strFileName" 等变量。
我正在创建上一个和下一个按钮来循环浏览文本文件中的每一行:
public void BtnNext_Click(object sender, EventArgs e)
{
StreamReader myReader2 = new StreamReader("colin.txt");
string line2 = "";
while (line2 != null)
{
line2 = myReader2.ReadLine();
if (line2 != null)
{
const char DELIM = '|';
// MessageBox.Show(line);
string[] word = line2.Split(DELIM);
Txt2NormAccNum.Text = word[3];
Txt3NormAmnt.Text = word[4];
Txt4NormFirstNam.Text = word[1];
Txt5NormLastNam.Text = word[2];
Txt6NormSS.Text = word[0];
Txt7NormItem.Text = word[5];
//Txt12ScrubSS.Text;
//Txt10ScrubFirstNam.Text;
//Txt11ScrubLastNam.Text;
//Txt8ScrubAcctNum.Text;
//Txt9ScrubAmt.Text;
//Txt13ScrubItem.Text;
}
}
myReader2.Close();
} // end method
如果你明白我在说什么:设计是:用户打开文件,文件中的第一行文本显示在表单上,然后我有一个“上一个”和 'next' 按钮,我想循环通过同一文件中的文本行。
@Tim 是的,我想我知道你在说什么看这里:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Project2_DataScrubber
{
public partial class Form1 : Form
{ // Begin Class #1
public Form1()
{ // Begin Main Method
InitializeComponent();
// MessageBox.Show(GetRandomNumbers().ToString());
} // End Main Method
private void Btn4_Click(object sender, EventArgs e)
{ // Btn4 CLICK Method
// Closes Form 1
this.Close();
} // End Method
private void Btn3_Click(object sender, EventArgs e)
{ // Btn3 CLICK Method
// Display alert message box of are you sure you want to reset the data
DialogResult dialogResult1 = MessageBox.Show("Are you want to reset the data?", "ALERT", MessageBoxButtons.YesNo);
if (dialogResult1 == DialogResult.Yes)
{
// Resets all the data, textboxes, ect
Txt1.Text = "No file loaded.";
Txt2NormAccNum.Clear();
Txt3NormAmnt.Clear();
Txt4NormFirstNam.Clear();
Txt5NormLastNam.Clear();
Txt6NormSS.Clear();
Txt7NormItem.Clear();
Txt8ScrubAcctNum.Clear();
Txt9ScrubAmt.Clear();
Txt10ScrubFirstNam.Clear();
Txt11ScrubLastNam.Clear();
Txt12ScrubSS.Clear();
Txt13ScrubItem.Clear();
Txt14ScrubYesNo.Clear();
LblStatus.Visible = false;
}
else if (dialogResult1 == DialogResult.No)
{
// Do nothing
}
} // End Method
public void Btn1_Click(object sender, EventArgs e)
{ // Btn1 CLICK Method
ScrubData();
} // End Method
public void Btn2_Click (object sender, EventArgs e)
{
if (Txt2NormAccNum.Text != "" || Txt3NormAmnt.Text != "" || Txt4NormFirstNam.Text != "" || Txt5NormLastNam.Text != "" ||
Txt6NormSS.Text != "" || Txt7NormItem.Text != "")
{
//
Txt12ScrubSS.Text = GetRandomNumbers().ToString(); // Replace SS textbox
//
#region
int lastNameLetters = Txt5NormLastNam.Text.Length; //
string lettersTwo = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random randLetters = new Random();
string randomString = "";
for (int i = 0; i < lastNameLetters; i++)
{ // Replace Last Name
randomString += lettersTwo
[randLetters.Next(0, 25)].ToString();
}
Txt11ScrubLastNam.Text = randomString; //
#endregion
#region
var newAccountNum = ""; //
int numOfCharacters = 4; // # to leave behind
for (var i = 0; i<Txt2NormAccNum.Text.Length - numOfCharacters; i++)
{
newAccountNum += "X"; // Replace Account Number
}
newAccountNum += Txt2NormAccNum.Text.Substring
(Txt2NormAccNum.Text.Length - numOfCharacters);
Txt8ScrubAcctNum.Text = newAccountNum; //
#endregion
#region
double moneyAmountDoub = 0; //
string moneyAmountStr = "";
moneyAmountStr = Txt3NormAmnt.Text;
moneyAmountDoub = Convert.ToDouble(moneyAmountStr);
if (moneyAmountDoub > 100.00)
{ // Get Yes or No answer
Txt14ScrubYesNo.Text = "Yes";
}
else
{
Txt14ScrubYesNo.Text = "No";
} //
#endregion
Txt10ScrubFirstNam.Text = Txt4NormFirstNam.Text;
Txt13ScrubItem.Text = Txt7NormItem.Text;
Txt13ScrubItem.Text = Txt7NormItem.Text;
Txt9ScrubAmt.Text = Txt3NormAmnt.Text;
}
else
{
MessageBox.Show("Error: Information missing from the Data section");
}
}
public void ScrubData()
{ // Begin Scrub Method
当然不是一行一行的。每次单击按钮时,您只是在阅读第一行。
最好的方法是将文件中的所有行读入 List<string>
并有一个 int counter
,你可以根据它们是向后还是向前移动来递增或递减。每次 increment/decrement 并将文本设置为 yourListVar[counter]
或者,如果您希望它每次都从文件中读取,您可以循环 ReadLine()
直到找到与计数器匹配的索引。
您需要做几件事。首先,您需要创建 class 级变量(更恰当地称为字段)来保存需要通过不同方法访问的信息。
其次,您需要跟踪文件中的位置(哪一行),因为每次创建 StreamReader
时,它都会将 reader 定位在第一行。作为必然结果,正如 RogueBukkitDev 所说,您应该读取文件一次并将其转储到 List<string>
或数组 (string[]
) 中。然后,您将根据用户的方向(向前或向后)增加或减少集合中的当前位置。
它可能看起来像这样:
public partial class Form1 : Form
{
// Class level fields
private string fileName = String.Empty;
private string[] fileLines;
private int currentLine = 0;
const char DELIM = '|';
public void ScrubData()
{
// Display an OpenFile Dialog box for user
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "txt Files|*.txt";
openFileDialog1.Title = "Select a txt File";
// Show the Dialog. If user clicked OK in the dialog
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
try
{
fileName = openFileDialog1.FileName;
newFileName = String.Format(@"{0}\{1}_scrubed.txt",
openFileDialog1.InitialDirectory,
Path.GetFileNameWithoutExtension(fileName));
fileLines = File.ReadAllLines(fileName);
currentLine = 0;
}
}
}
public void BtnNext_Click(object sender, EventArgs e)
{
if (currentLine <= fileLines.Length)
{
string line2 = fileLines[currentLine];
string[] word = line2.Split(DELIM);
Txt2NormAccNum.Text = word[3];
Txt3NormAmnt.Text = word[4];
Txt4NormFirstNam.Text = word[1];
Txt5NormLastNam.Text = word[2];
Txt6NormSS.Text = word[0];
Txt7NormItem.Text = word[5];
currentLine = currentLine + 1;
}
}
}
这里有很多变化,我省略了与示例无关的代码。
首先,我声明了 4 个字段 - 一个用于文件名,一个用于清理后的文件名,一个用于文件的当前行,一个常量用于分隔符。
接下来,在 ScrubData
方法中,用户选择了文件,它只需调用 File.ReadAllLines()
,这将 return 一个字符串数组(每行一个数组元素),并将其存储在 class 级别字段 fileLines
中。它还将 currentLine
设置为 0,以防用户在退出程序前选择不同的文件。
在 btnNext_Click
事件处理程序中,它从行数组 (fileLines
) 中读取当前行 - 在确保不会出现索引越界错误之后,然后将它们拆分在分隔符上并填充文本框。然后它将 currentLine
增加一。
返回,本质上是相同的逻辑,除了你会减少currentLine
1(并检查以确保你不去过去 0).
这是我们一直试图解释的内容的基本轮廓。您可能需要根据自己的实际需要进行修改,但原理是一样的。
在 BtnNext_Click
方法中,它只是从文本文件中读取,就像它是另一个文本文件一样,而不是从已经打开的文件中读取。它不会从一行到另一行。
我需要帮助
代码如下:
public void ScrubData()
{
string FileName1;
string FilePath1;
// Display an OpenFile Dialog box for user
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "txt Files|*.txt";
openFileDialog1.Title = "Select a txt File";
// Show the Dialog. If user clicked OK in the dialog
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
try
{
String strFileName = openFileDialog1.FileName;
String strFilePath = System.IO.Path.GetDirectoryName(strFileName);
String fileName = System.IO.Path.GetFileNameWithoutExtension(strFileName);
String strFileNameAndPathNew = strFilePath +
openFileDialog1.InitialDirectory + "\" + fileName + "_scrubbed.txt";
// If scrubbed file exists, delete it first
if (System.IO.File.Exists(strFileNameAndPathNew))
{
System.IO.File.Delete(strFileNameAndPathNew);
} // End IF
if (System.IO.File.Exists(strFileName))
{
int lineCount = System.IO.File.ReadAllLines(strFileName).Length;
System.IO.StreamReader file = new System.IO.StreamReader(strFileName);
// Status label
LblStatus.Text = "File Loaded Successfully";
LblStatus.Visible = true;
string line;
while ((line = file.ReadLine()) != null)
{
const char DELIM = '|';
// MessageBox.Show(line);
string[] word = line.Split(DELIM);
Txt2NormAccNum.Text = word[3];
//string accScrubbed = ReplaceData(word[0],"SSN");
Txt3NormAmnt.Text = word[4];
Txt4NormFirstNam.Text = word[1];
Txt5NormLastNam.Text = word[2];
Txt6NormSS.Text = word[0];
Txt7NormItem.Text = word[5];
} // End WHILE
} // End IF
else
{
// Status label
LblStatus.Text = "File Load Failed!";
LblStatus.Visible = true;
} // End ELSE
// Text box one code:
FileName1 = openFileDialog1.FileName;
Txt1.Text = FileName1;
//
} // End TRY
catch (Exception e1)
{
if (e1.Source != null)
{
Console.WriteLine("IOException source: {0}", e1.Source);
throw;
} // End IF
} // End CATCH
} // End IF
} // End Scrub Method
我需要在下一个方法中重用 "strFileName" 等变量。
我正在创建上一个和下一个按钮来循环浏览文本文件中的每一行:
public void BtnNext_Click(object sender, EventArgs e)
{
StreamReader myReader2 = new StreamReader("colin.txt");
string line2 = "";
while (line2 != null)
{
line2 = myReader2.ReadLine();
if (line2 != null)
{
const char DELIM = '|';
// MessageBox.Show(line);
string[] word = line2.Split(DELIM);
Txt2NormAccNum.Text = word[3];
Txt3NormAmnt.Text = word[4];
Txt4NormFirstNam.Text = word[1];
Txt5NormLastNam.Text = word[2];
Txt6NormSS.Text = word[0];
Txt7NormItem.Text = word[5];
//Txt12ScrubSS.Text;
//Txt10ScrubFirstNam.Text;
//Txt11ScrubLastNam.Text;
//Txt8ScrubAcctNum.Text;
//Txt9ScrubAmt.Text;
//Txt13ScrubItem.Text;
}
}
myReader2.Close();
} // end method
如果你明白我在说什么:设计是:用户打开文件,文件中的第一行文本显示在表单上,然后我有一个“上一个”和 'next' 按钮,我想循环通过同一文件中的文本行。
@Tim 是的,我想我知道你在说什么看这里:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Project2_DataScrubber
{
public partial class Form1 : Form
{ // Begin Class #1
public Form1()
{ // Begin Main Method
InitializeComponent();
// MessageBox.Show(GetRandomNumbers().ToString());
} // End Main Method
private void Btn4_Click(object sender, EventArgs e)
{ // Btn4 CLICK Method
// Closes Form 1
this.Close();
} // End Method
private void Btn3_Click(object sender, EventArgs e)
{ // Btn3 CLICK Method
// Display alert message box of are you sure you want to reset the data
DialogResult dialogResult1 = MessageBox.Show("Are you want to reset the data?", "ALERT", MessageBoxButtons.YesNo);
if (dialogResult1 == DialogResult.Yes)
{
// Resets all the data, textboxes, ect
Txt1.Text = "No file loaded.";
Txt2NormAccNum.Clear();
Txt3NormAmnt.Clear();
Txt4NormFirstNam.Clear();
Txt5NormLastNam.Clear();
Txt6NormSS.Clear();
Txt7NormItem.Clear();
Txt8ScrubAcctNum.Clear();
Txt9ScrubAmt.Clear();
Txt10ScrubFirstNam.Clear();
Txt11ScrubLastNam.Clear();
Txt12ScrubSS.Clear();
Txt13ScrubItem.Clear();
Txt14ScrubYesNo.Clear();
LblStatus.Visible = false;
}
else if (dialogResult1 == DialogResult.No)
{
// Do nothing
}
} // End Method
public void Btn1_Click(object sender, EventArgs e)
{ // Btn1 CLICK Method
ScrubData();
} // End Method
public void Btn2_Click (object sender, EventArgs e)
{
if (Txt2NormAccNum.Text != "" || Txt3NormAmnt.Text != "" || Txt4NormFirstNam.Text != "" || Txt5NormLastNam.Text != "" ||
Txt6NormSS.Text != "" || Txt7NormItem.Text != "")
{
//
Txt12ScrubSS.Text = GetRandomNumbers().ToString(); // Replace SS textbox
//
#region
int lastNameLetters = Txt5NormLastNam.Text.Length; //
string lettersTwo = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random randLetters = new Random();
string randomString = "";
for (int i = 0; i < lastNameLetters; i++)
{ // Replace Last Name
randomString += lettersTwo
[randLetters.Next(0, 25)].ToString();
}
Txt11ScrubLastNam.Text = randomString; //
#endregion
#region
var newAccountNum = ""; //
int numOfCharacters = 4; // # to leave behind
for (var i = 0; i<Txt2NormAccNum.Text.Length - numOfCharacters; i++)
{
newAccountNum += "X"; // Replace Account Number
}
newAccountNum += Txt2NormAccNum.Text.Substring
(Txt2NormAccNum.Text.Length - numOfCharacters);
Txt8ScrubAcctNum.Text = newAccountNum; //
#endregion
#region
double moneyAmountDoub = 0; //
string moneyAmountStr = "";
moneyAmountStr = Txt3NormAmnt.Text;
moneyAmountDoub = Convert.ToDouble(moneyAmountStr);
if (moneyAmountDoub > 100.00)
{ // Get Yes or No answer
Txt14ScrubYesNo.Text = "Yes";
}
else
{
Txt14ScrubYesNo.Text = "No";
} //
#endregion
Txt10ScrubFirstNam.Text = Txt4NormFirstNam.Text;
Txt13ScrubItem.Text = Txt7NormItem.Text;
Txt13ScrubItem.Text = Txt7NormItem.Text;
Txt9ScrubAmt.Text = Txt3NormAmnt.Text;
}
else
{
MessageBox.Show("Error: Information missing from the Data section");
}
}
public void ScrubData()
{ // Begin Scrub Method
当然不是一行一行的。每次单击按钮时,您只是在阅读第一行。
最好的方法是将文件中的所有行读入 List<string>
并有一个 int counter
,你可以根据它们是向后还是向前移动来递增或递减。每次 increment/decrement 并将文本设置为 yourListVar[counter]
或者,如果您希望它每次都从文件中读取,您可以循环 ReadLine()
直到找到与计数器匹配的索引。
您需要做几件事。首先,您需要创建 class 级变量(更恰当地称为字段)来保存需要通过不同方法访问的信息。
其次,您需要跟踪文件中的位置(哪一行),因为每次创建 StreamReader
时,它都会将 reader 定位在第一行。作为必然结果,正如 RogueBukkitDev 所说,您应该读取文件一次并将其转储到 List<string>
或数组 (string[]
) 中。然后,您将根据用户的方向(向前或向后)增加或减少集合中的当前位置。
它可能看起来像这样:
public partial class Form1 : Form
{
// Class level fields
private string fileName = String.Empty;
private string[] fileLines;
private int currentLine = 0;
const char DELIM = '|';
public void ScrubData()
{
// Display an OpenFile Dialog box for user
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "txt Files|*.txt";
openFileDialog1.Title = "Select a txt File";
// Show the Dialog. If user clicked OK in the dialog
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
try
{
fileName = openFileDialog1.FileName;
newFileName = String.Format(@"{0}\{1}_scrubed.txt",
openFileDialog1.InitialDirectory,
Path.GetFileNameWithoutExtension(fileName));
fileLines = File.ReadAllLines(fileName);
currentLine = 0;
}
}
}
public void BtnNext_Click(object sender, EventArgs e)
{
if (currentLine <= fileLines.Length)
{
string line2 = fileLines[currentLine];
string[] word = line2.Split(DELIM);
Txt2NormAccNum.Text = word[3];
Txt3NormAmnt.Text = word[4];
Txt4NormFirstNam.Text = word[1];
Txt5NormLastNam.Text = word[2];
Txt6NormSS.Text = word[0];
Txt7NormItem.Text = word[5];
currentLine = currentLine + 1;
}
}
}
这里有很多变化,我省略了与示例无关的代码。
首先,我声明了 4 个字段 - 一个用于文件名,一个用于清理后的文件名,一个用于文件的当前行,一个常量用于分隔符。
接下来,在 ScrubData
方法中,用户选择了文件,它只需调用 File.ReadAllLines()
,这将 return 一个字符串数组(每行一个数组元素),并将其存储在 class 级别字段 fileLines
中。它还将 currentLine
设置为 0,以防用户在退出程序前选择不同的文件。
在 btnNext_Click
事件处理程序中,它从行数组 (fileLines
) 中读取当前行 - 在确保不会出现索引越界错误之后,然后将它们拆分在分隔符上并填充文本框。然后它将 currentLine
增加一。
返回,本质上是相同的逻辑,除了你会减少currentLine
1(并检查以确保你不去过去 0).
这是我们一直试图解释的内容的基本轮廓。您可能需要根据自己的实际需要进行修改,但原理是一样的。