我正在开发一个处理由Cobol系统生成的顺序文件的系统,目前,我正在使用几个子串进行数据处理以获取数据,但我想知道是否有更有效的方法来处理文件而不是制作几个子串...
现在,我基本上做了:
using (var sr = new StreamReader("file.txt"))
{
String line = "";
while(!sr.EndOfStream)
{
line = sr.ReadLine();
switch(line[0])
{
case '0':
processType0(line);
break;
case '1':
processType1(line);
break;
case '2':
processType2(line);
break;
case '9':
processType9(line);
break;
}
}
}
private void processType0(string line)
{
type = line.Substring(0, 15);
name = line.Substring(15, 30);
//... and more 20 substrings
}
private void processType1(string line)
{
// 45 substrings...
}
文件大小可能在50mb到150mb之间变化...... 文件的一个小例子:
01ARQUIVO01CIVDSUQK 00000000000000999999NAME NAME NAME NAME 892DATAFILE 200616 KY0000853 000001
1000000000000000000000000999904202589ESMSS59365 00000010000000000000026171900000000002 0 01000000000001071600000099740150000000001N020516000000000000000000000000000000000000000000000000000000000000009800000000000000909999-AAAAAAAAAAAAAAAAAAAAAAAAA 00000000 000002
1000000000000000000000000861504202589ENJNS63198 00000010000000000000036171300000000002 0 01000000000001071600000081362920000000001N020516000000000000000000000000000000000000000000000000000000000000009800000000000000909999-BBBBBBBBBBBBBBBBBBBBBBBBBB 00000000 000003
9 000004
答案 0 :(得分:2)
频繁的磁盘读取会降低代码速度。
根据MSDN,constructor you are using的缓冲区大小为1024字节。 使用不同的构造函数设置更大的缓冲区大小:
int bufferSize = 1024 * 128;
using (var reader = new StreamReader(path, encoding, autoDetectEncoding, bufferSize))
{
...
}
C#优先考虑安全性超速,因此所有String函数都会生成一个新字符串。
你真的需要所有这些子串吗?如果没有,那么只需生成你需要的那些:
private static string GetType(string line)
{
return line.Substring(0, 15);
}
if (needed)
type = GetLine(line);
答案 1 :(得分:1)
您可以尝试编写一个解析器,一次处理一个字符。
我读了一篇名为' Writing a parser for CSV data'关于如何使用CSV文件进行此操作的日子,尽管大多数文件类型的主体是相同的。这可以在http://www.boyet.com/articles/csvparser.html
找到答案 2 :(得分:1)
第一次使用C#,但我想你想看看像
这样的东西struct typeOne {
fixed byte recordType[1];
fixed byte whatThisFieldIsCalled[10];
fixed byte someOtherFieldName[5];
...
}
然后只按行[0]大小写分配不同的结构。或者,知道Nada旁边有关C#的内容,这可能是完全错误的球场,并最终在内部表现不佳。
答案 3 :(得分:0)
我爱Linq
IEnumerable<string> ReadFile(string path)
{
using (var reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
yield return reader.ReadLine();
}
}
}
void DoThing()
{
var myMethods = new Action<string>[]
{
s =>
{
//Process 0
type = line.Substring(0, 15);
name = line.Substring(15, 30);
//... and more 20 substrings
},
s =>
{
//Process 1
type = line.Substring(0, 15);
name = line.Substring(15, 30);
//... and more 20 substrings
},
//...
}
var actions = ReadFile(@"c:\path\to\file.txt")
.Select(line => new Action( () => myMethods[int.Parse(line[0])]() ))
.ToArray();
actions.ForEach(a => a.Invoke());
}