C#确定平面文件中的EOL字符

时间:2014-09-15 17:25:27

标签: c# eol

我试图从给定的.txt或.csv平面文件中识别EOL字符。基于EOL字符来自平面文件中的第一行数据,我想相应地处理此文件中的数据(我使用批量加载在SQL Server上创建表并需要将EOL传递给批量加载命令)。据我所知,Readline()自动处理EOL,因此我无法解析EOL字符的Readline()字符串。下面的代码给出了我想要做的一个例子:

int EOLChar_CRLF = 0;
int EOLChar_LF = 0;
int EOLChar_CR = 0;
int EOLChar_Hex = 0;

string eol_line = file2.ReadLine();
MessageBox.Show(eol_line);
EOLChar_CRLF = eol_line.IndexOf("\\r\\\n");
EOLChar_LF = eol_line.IndexOf("\\n");
EOLChar_CR = eol_line.IndexOf("\\r");
EOLChar_Hex = eol_line.IndexOf("\\0x0a");

MessageBox.Show("CRLF is line feed if " + EOLChar_CRLF.ToString() + " <> -1");
MessageBox.Show("LF is line feed if " + EOLChar_LF.ToString() + " <> -1");
MessageBox.Show("CR is line feed if " + EOLChar_CR.ToString() + " <> -1");
MessageBox.Show("0x0a is line feed if " + EOLChar_Hex.ToString() + " <> -1");

有没有人知道使用StreamReader.ReadLine()方法或任何其他方法来确定EOL的方法?我只想读取第一行数据并解析EOL,因为其中一些文件是超过2000万行。

1 个答案:

答案 0 :(得分:4)

确定文本文件的行尾约定的常用方法是从文件开头填入足够大小的缓冲区并检查它。当然,缓冲区的大小在某种程度上取决于预期的行长度。你想要填充足够的数据以获得合理数量的行。

除了Windows(CR + LF),Unix / Linux / OS X(LF)或老式MacOS(CR)之外,您不太可能遇到行尾约定。对于速度,很难打败这样的东西。

public enum EndOfLineStyle
{
  Unknown = 0     ,
  CR      = 1     ,
  LF      = 2     ,
  CRLF    = CR|LF ,
  Unix    = LF    ,
  MacOs   = CR    ,
  Windows = CRLF  ,
}

const int BUFFER_SIZE = 8192 ;
public EndOfLineStyle DetermineEndOfLineStyle( string pathToFile )
{
  int    bufl  = 0 ;
  char[] buf   = new char[BUFFER_SIZE] ;

  using ( StreamReader reader = File.OpenText( pathToFile ) )
  {
    bufl = reader.ReadBlock( buf , 0 , buf.Length ) ;
  }

  int crlfs = 0 ;
  int crs   = 0 ;
  int lfs   = 0 ;

  for ( int i = 0 ; i < bufl ; )
  {
    if      ( buf[i] == '\r' && i < bufl-1 && buf[i+1] == '\n' ) { ++crlfs ; i+=2 ; }
    else if ( buf[i] == '\r'                                   ) { ++crs   ; i+=1 ; }
    else if ( buf[i] == '\n' )                                   { ++lfs   ; i+=1 ; }
  }

  EndOfLineStyle style ;
  if      ( crlfs > crs   && crlfs > lfs ) style = EndOfLineStyle.Windows ;
  else if ( lfs   > crlfs && lfs   > crs ) style = EndOfLineStyle.Unix    ;
  else if ( crs   > crlfs && crs   > lfs ) style = EndOfLineStyle.MacOs   ;
  else                                     style = EndOfLineStyle.Unknown ;

  return style ;
}