我需要逐行读取字符(^)分隔的文本文件并替换同一文件中的错误数据。我当前的程序可以做到这一点,但我想知道如果需要处理巨大的文本文件,是否有更有效的方法来做到这一点。
输入文件数据:
10^I^23231^LGGE^DTL^09595~
20^00001^11^0.03000^0.05000^0.40500^EXETER~
30^223312^R^700^12.90^10^~
40^R^70036700015^01~
50^00000^12~
30^000000^C^781^11.10^09~
40^R^70036700016^01~
50^00000^12~
90^007^20231208^090909^0001^11~
行号 10 表示标题,90 表示尾部,中间的所有内容都是详细信息行,每个行号对应于一个特定属性,如合同详细信息或订单详细信息或供应商详细信息。
我的代码查找不正确的供应商详细信息(即第 30 行)并检查第 2 列中的供应商编号是否有效。如果是 000000,则替换为默认值“221212”。对于下一个行号 30 循环重复此过程,直到 EOF。 这些行具有不同数量的实体,但具有相同起始行号的行具有相同数量的实体。 StreamReader 类确实可以工作,但是我想知道是否有更有效的解决方案可用。尝试了 FileHelpers dll,但无法让它按预期工作来获取和替换确切的值。
代码:
public chkfile()
{
string[] ipFields = null;
ArrayList nextpos = new ArrayList();
StreamReader reader = new StreamReader("inputfile.txt");
nextpos.Add("30");
string res = string.Empty;
while (reader.Peek() >= 0)
{
fileLine = reader.ReadLine().Trim();
lineLength = fileLine.Length;
int lineLength_a = fileLine.Length - 1;
// Gets the ipFields from the file
recordType = fileLine.Substring(0, 2);
ipFields = fileLine.Substring(0, lineLength).Split
(Configuration.ipFile.ColumnDelimiter.ToCharArray());
if (fileLine.StartsWith("30") && nextpos.Contains("30"))
{
for (int i = 0; i < ipFields.Length; i++)
{
if (ipFields[i].Equals("000000"))
{
ipFields[i] = ipFields[i].Replace(ipFields[i], "221212");
}
}
res = string.Join(Configuration.ipFile.ColumnDelimiter, ipFields);
ipFileContent = ipFileContent.Replace(fileLine, res);
// Set the next expected record type
nextpos.Clear();
nextpos.Add("40");
}
}
}
public class ipFile
{
/// <summary>
/// Value that delimits the Rows
/// </summary>
public static string RowDelimiter
{
get { return "~"; }
}
/// <summary>
/// Value that delimits the ipFields
/// </summary>
public static string ColumnDelimiter
{
get { return "^"; }
}
}
您上面提供的代码对于逐行处理输入文件并根据某些条件进行替换似乎是合理的。唯一的事情是你可以优化它。如果您正在处理非常大的文本文件,则应考虑一些优化:
1。内存使用情况:
ArrayList
来加快查找速度,而不是使用 nextpos
来代替 HashSet
。StringBuilder
构建修改后的内容。2。文件输入/输出:
StreamReader
包裹在 using
声明中,以确保完成后得到正确处置。以下是包含其中一些建议的示例:
public class chkfile
{
public chkfile()
{
HashSet<string> nextpos = new HashSet<string> { "30" };
using (StreamReader reader = new StreamReader("inputfile.txt"))
using (StreamWriter writer = new StreamWriter("outputfile.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
string[] ipFields = line.Split(Configuration.ipFile.ColumnDelimiter.ToCharArray());
if (line.StartsWith("30") && nextpos.Contains("30"))
{
for (int i = 0; i < ipFields.Length; i++)
{
if (ipFields[i].Equals("000000"))
{
ipFields[i] = "221212";
}
}
line = string.Join(Configuration.ipFile.ColumnDelimiter, ipFields);
// Set the next expected record type
nextpos.Clear();
nextpos.Add("40");
}
writer.WriteLine(line);
}
}
}
}
请记住将
outputfile.txt
替换为您想要的输出文件名。这种方法减少了内存使用量,尤其是在处理大文件时,并确保正确的文件 I/O 处理。