Mik*_*ron 4 .net c# newline sed
我有一个问题应该让大多数人都去"WTF?",但我仍然拥有它.
我从供应商处获得了大量数据文件.它采用自定义平面文件格式,声称为CSV,但不以逗号分隔,并且不引用值.所以,根本不是真正的CSV.
foo,bar,baz
alice,bob,chris
Run Code Online (Sandbox Code Playgroud)
等等,除了更长,更少有趣.问题是,有些记录嵌入了换行符(!!!):
foo,bar
rab,baz
alice,bob,chris
Run Code Online (Sandbox Code Playgroud)
这应该是每个三个字段的两个记录.通常情况下,我只会说"不,这是愚蠢的.",但我不经意地看得更近了,发现它实际上是一种不同于实际行结束序列的行尾:
foo,bar\n
rab,baz\r\n
alice,bob,chris\r\n
Run Code Online (Sandbox Code Playgroud)
注意第一行上的\n.我已经确定这适用于我发现嵌入式换行的所有情况.所以,我需要基本上做s/\n$//(我尝试了这个特定的命令,它没有做任何事情).
注意:我实际上并不关心字段的内容,因此无需更换换行符.我只需要文件中的每一行都有相同数量的记录(理想情况下,在同一个地方).
我在处理文件的工具中有一个现有的解决方案:
Guid g = Guid.NewGuid();
string data = File.ReadAllText(file, Encoding.GetEncoding("Latin1"));
data = data.Replace("\r\n", g.ToString()); //just so I have a unique placeholder
data = data.Replace("\n", "");
data = data.Replace(g.ToString(), "\r\n");
Run Code Online (Sandbox Code Playgroud)
但是,对于大于千兆字节左右的文件,这会失败.(另外,我没有对它进行分析,但我怀疑它的狗也很慢).
我可以使用的工具是:
做这个的最好方式是什么?
而不是将整个事物作为一个大的(可能是巨大的)字符串读入内存,而是考虑基于流的方法.
打开输入流并一次读取一行,根据需要进行替换.打开输出流并将修改后的行写入其中.就像是:
static void Main( string[] args )
{
using( var inFs = File.OpenRead( @"C:\input.txt" ) )
using( var reader = new StreamReader( inFs ) )
using( var outFs = File.Create( @"C:\output.txt" ) )
using( var writer = new StreamWriter( outFs ) )
{
int cur;
char last = '0';
while( ( cur = reader.Read() ) != -1 )
{
char next = (char)reader.Peek();
char c = (char)cur;
if( c != '\n' || last == '\r' )
writer.Write( c );
last = c;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1661 次 |
| 最近记录: |