0

我正在尝试从文本文件中获取某些字符串并将其放入变量中。这是文本文件的结构,请记住,这只是一行,每一行看起来像这样,并由一个空行分隔:

Date: 8/12/2013 12:00:00 AM Source Path: \\build\PM\11.0.64.1\build.11.0.64.1.FileServerOutput.zip Destination Path: C:\Users\Documents\.NET Development\testing\11.0.64.1\build.11.0.55.5.FileServerOutput.zip Folder Updated: 11.0.64.1 File Copied: build.11.0.55.5.FileServerOutput.zip

我不太确定该文本文件的分隔符使用什么,或者即使我应该使用分隔符以便它可能会发生变化。

所以只是我想要发生的事情的一个简单示例,我想通过并获取目标路径并将其存储在诸如 strDestPath 之类的变量中。

总的来说,到目前为止我想出的代码是这样的:

//find the variables from the text file
string[] lines = File.ReadAllLines(GlobalVars.strLogPath);

是的,不多,但我想也许我一次只阅读一行并尝试通过该行搜索我正在寻找的东西,但老实说,我不能 100% 确定我是否应该坚持这种方式。 ..

4

3 回答 3

4

如果您对文件的大小持怀疑态度,您应该使用ReadLineswhich is deferred execution而不是ReadAllLines

var lines = File.ReadLines(GlobalVars.strLogPath);

ReadLines和方法的ReadAllLines区别如下:

使用 ReadLines 时,可以在返回整个集合之前开始枚举字符串集合;使用 ReadAllLines 时,必须等待返回整个字符串数组才能访问该数组。因此,当您处理非常大的文件时,ReadLines 会更有效率。

于 2013-08-15T16:04:15.957 回答
2

尽管听起来很奇怪,但您应该看一下日志解析器。如果您可以自由设置文件格式,您可以使用适合日志解析器的文件格式,相信我,它会让您的生活更轻松。

使用日志解析加载文件后,您可以用户查询以获取所需的信息。如果您不关心在您的项目中使用互操作,您甚至可以添加一个 com 引用并从任何 .net 项目中使用它。

此示例读取一个巨大的 csv 文件,并批量复制到数据库以在那里执行最后的步骤。这不是你的情况,但向你展示了使用 logparser 做到这一点是多么容易

COMTSVInputContextClass logParserTsv = new COMTSVInputContextClass();
COMSQLOutputContextClass logParserSql = new COMSQLOutputContextClass();
logParserTsv.separator = ";";
logParserTsv.fixedSep = true;

logParserSql.database = _sqlDatabaseName;
logParserSql.server = _sqlServerName;
logParserSql.username = _sqlUser;
logParserSql.password = _sqlPass;
logParserSql.createTable = false;
logParserSql.ignoreIdCols = true;

// query shortened for clarity purposes
string SelectPattern = @"Select  TO_STRING(UserName),TO_STRING(UserID) INTO {0}  From {1}";

string query = string.Format(SelectPattern, _sqlTable, _csvPath);
logParser.ExecuteBatch(query, logParserTsv, logParserSql);

LogParser 是微软拥有但大多数人不知道的隐藏宝石之一。我曾经用来阅读iis日志、CSV文件、txt文件等。你甚至可以生成图形!!!

只需在此处查看http://support.microsoft.com/kb/910447/en

于 2013-08-15T17:26:30.270 回答
1

看起来您需要创建一个 Tokenizer。尝试这样的事情:

定义标记值列表:

List<string> gTkList = new List<string>() {"Date:","Source Path:" }; //...etc.

创建一个 Token 类:

public class Token
{
  private readonly string _tokenText;
  private string _val;
  private int _begin, _end;

  public Token(string tk, int beg, int end)
  {
   this._tokenText = tk;
   this._begin = beg;
   this._end = end;
   this._val = String.Empty;
  }

  public string TokenText
  {
   get{ return _tokenText; }
  }

  public string Value
  {
   get { return _val; }
   set { _val = value; }
  }

  public int IdxBegin
  {
   get { return _begin; }
  }

  public int IdxEnd
  {
   get { return _end; }
  }
}

创建一个查找令牌的方法:

List<Token> FindTokens(string str)
{
 List<Token> retVal = new List<Token>();
 if (!String.IsNullOrWhitespace(str))
 {
  foreach(string cd in gTkList)
  {
    int fIdx = str.IndexOf(cd);
    if(fIdx > -1)
       retVal.Add(cd,fIdx,fIdx + cd.Length);
  }      
 }
 return retVal;
}

然后做这样的事情:

foreach(string ln in lines)
{
 //returns ordered list of tokens
 var tkns = FindTokens(ln);
 for(int i=0; i < tkns.Length; i++)
 {
  int len = (i == tkns.Length - 1) ? ln.Length - tkns[i].IdxEnd : tkns[i+1].IdxBegin - tkns[i].IdxEnd;
  tkns[i].value = ln.Substring(tkns[i].IdxEnd+1,len).Trim();
 }

 //Do something with the gathered values
 foreach(Token tk in tkns)
 {
  //stuff
 }
}
于 2013-08-15T18:57:01.453 回答