我使用以下代码从访问源中提取数据,以将其作为制表符分隔的文件逐行写入。
private static void WriteFlatFile(string pathAndFileName, string connString)
{
if (File.Exists(pathAndFileName))
{
File.Delete(pathAndFileName);
}
using (OleDbConnection conn = new OleDbConnection(connString))
{
OleDbCommand cmd = new OleDbCommand("SELECT X, Y, Z FROM SomeAmazingTable", conn);
conn.Open();
OleDbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
var newContent = string.Format(
"{0}t{1}"
, reader.GetValue(0).ToString().Trim()
, reader.GetValue(1).ToString().Trim()
);
File.AppendAllText(pathAndFileName, newContent + Environment.NewLine);
}
reader.Close();
}
}
不幸的是,这非常缓慢。有什么我可以改进/改变的吗?
如果您验证了数据库查询速度很快 - 问题出在将数据写入文件的方式上。 File.AppendAllText
将打开文件,在那里附加数据,然后关闭文件。这种紧密循环中的打开和关闭会降低性能,在这里完全没有必要。相反,在 while 循环之外打开文件一次,然后在那里写入:
using (var fs = new StreamWriter(pathAndFileName)) {
while (reader.Read()) {
var newContent = string.Format(
"{0}t{1}"
, reader.GetValue(0).ToString().Trim()
, reader.GetValue(1).ToString().Trim()
);
fs.WriteLine(newContent);
}
}
为什么不将所有数据放在带有新行信息的字符串变量中,一旦完成读取,只需打开文件一次并在一次尝试中将所有数据写入。
string stream = "";
using (OleDbConnection conn = new OleDbConnection(connString))
{
OleDbCommand cmd = new OleDbCommand("SELECT X, Y, Z FROM SomeAmazingTable", conn);
conn.Open();
OleDbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
var newContent = string.Format(
"{0}t{1}"
, reader.GetValue(0).ToString().Trim()
, reader.GetValue(1).ToString().Trim()
);
stream = newContent + Environment.NewLine;
}
File.WriteAllText(pathAndFileName, stream);
reader.Close();
}