我正在编写一个将数据库表写入CSV文件的应用程序。由于许多表都有超过一百万条记录,因此我向用户提供了将大表写入每个25,000行的文件的选项。我希望用户在SaveFileDialog中指定初始文件名,然后为每个写入的新文件附加“-part1”,“ - part2”等。在编写所有数据之前,如何以编程方式编写多个文件?我必须编写25,000行文件的当前代码如下所示。
public void ExportPartition(SaveFileDialog saveFile, DataTable table)
{
TextWriter writer = new StreamWriter(saveFile.FileName, true, System.Text.Encoding.ASCII, 1048576);
for (int i = 0; i <= 25000; i++)
{
for (int j = 0; j < table.Columns.Count; j++)
{
writer.Write(table.Rows[i][j].ToString() + ",");
}
writer.Write("\r\n");
}
writer.Flush();
DisposeObjects(saveFile, writer);
}
答案 0 :(得分:0)
bool ExportPartition(string fileName, DataTable table, int batchSize, int batchNum)
{
string fn = string.Format("{0}-{1}{2}",
Path.GetFileNameWithoutExtension(fileName),
batchNum,
Path.GetExtension(fileName));
fn = Path.Combine(Path.GetDirectoryName(fileName), fn);
using (TextWriter writer = new StreamWriter(fn))
{
int start = batchNum * batchSize;
int end = start + batchSize;
for (int i = start; i < end; i++)
{
if (i >= table.Rows.Count)
break;
for (int j = 0; j < table.Columns.Count; j++)
{
writer.Write(table.Rows[i][j] + ",");
}
writer.Write("\r\n");
}
return table.Rows.Count <= end;
}
}
用法:
void WriteFiles(DataTable table, String fileName, int batchSize)
{
int batchNum = 0;
bool done = false;
while (!done)
{
done = ExportPartition(fileName, table, batchSize, batchNum++);
}
}
void Main()
{
DataTable dt = GetData();
string fileName = GetFileNameWithSaveDialog();
int batchSize = 25000;
WriteFiles(dt, fileName, batchSize);
}
答案 1 :(得分:0)
另一种解决方案:
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Col1");
dt.Columns.Add("Col2");
for (int i = 0; i < 103; ++i)
{
var r = dt.NewRow();
r[0] = Guid.NewGuid().ToString();
r[1] = i.ToString();
dt.Rows.Add(r);
}
WriteCsvFile(dt, 25, @"C:\temp\test.txt");
}
public static string[] ToStringArray(DataRow row)
{
var arr = new string[row.Table.Columns.Count];
for (int j = 0; j < arr.Length; j++)
{
arr[j] = row[j].ToString();
if((arr[j]??"").Contains(","))
throw new Exception("This will end badly...");
}
return arr;
}
public static void WriteCsvFile(DataTable table, int maxCount, string fileName)
{
if (table.Rows.Count <= maxCount)
WriteCsvFile(table, maxCount, fileName, 0);
else
for (int i = 0; i < (table.Rows.Count / maxCount + 1); ++i)
{
var partFileName = Path.Combine(Path.GetDirectoryName(fileName), string.Format("{0}-part{1}{2}", Path.GetFileNameWithoutExtension(fileName), i+1, Path.GetExtension(fileName)));
WriteCsvFile(table, maxCount, partFileName, i * maxCount);
}
}
public static void WriteCsvFile(DataTable table, int maxCount, string fileName, int startIndex)
{
using(var fs = File.Create(fileName))
using(var w = new StreamWriter(fs, Encoding.ASCII))
{
for (int i = startIndex; i < Math.Min(table.Rows.Count, startIndex + maxCount); i++)
w.WriteLine(String.Join(",", ToStringArray(table.Rows[i])));
w.Flush();
}
}
}