我有这样的文本文件:
"01","AAA","AAAAA"
"02","BBB","BBBBB","BBBBBBBB"
"03","CCC"
"04","DDD","DDDDD"我想把这个文本文件数据加载到sybase db的临时表中。因此,我需要构建一个程序来逐行读取这个文本文件,直到eof。如果文本文件较小,则逐行读取的过程较快。但是如果文本文件太大(可能超过500M),逐行读取的过程就会太慢。我认为逐行读取的方法不适合大型文本文件。因此,需要寻找其他解决方案,将文本文件数据加载到数据库中,而不是逐行读取文本文件。有什么建议吗?示例代码:
var
myFile : TextFile;
text : string;
begin
// Try to open the Test.txt file for writing to
AssignFile(myFile, 'Test.txt');
// Display the file contents
while not Eof(myFile) do
begin
ReadLn(myFile, text);
TempTable.append;
TempTable.FieldByName('Field1').asstring=Copy(text,2,2);
TempTable.FieldByName('Field2').asstring=Copy(text,7,3);
TempTable.FieldByName('Field3').asstring=Copy(text,13,5);
TempTable.FieldByName('Field4').asstring=Copy(text,21,8);
TempTable.post;
end;
// Close the file for the last time
CloseFile(myFile);
end;发布于 2013-07-18 14:00:36
一些一般提示:
TempTable在内存中,或使用快速的数据库引擎-看看SQlite3或其他方法(如FireBird embedded,NexusDB或ElevateDB)作为可能的数据库alternatives;TTable一个真正的数据库,检查如果你不能使用ArrayDML功能,这是更快的插入大量数据,因为你想在一个远程数据库(如Sybase) - such Array DML is handled for instance with AFAIK;FieldByName('...')方法众所周知非常慢:使用本地变量TField变量使用TextFile,分配更大的临时缓冲区;所以你的代码可能是:
var
myFile : TextFile;
myFileBuffer: array[word] of byte;
text : string;
Field1, Field2, Field3, Field4: TField;
begin
// Set Field* local variables for speed within the main loop
Field1 := TempTable.FieldByName('Field1');
Field2 := TempTable.FieldByName('Field2');
Field3 := TempTable.FieldByName('Field3');
Field4 := TempTable.FieldByName('Field4');
// Try to open the Test.txt file for writing to
AssignFile(myFile, 'Test.txt');
SetTextBuf(myFile, myFileBuffer); // use 64 KB read buffer
// Display the file contents
while not Eof(myFile) do
begin
ReadLn(myFile, text);
TempTable.append;
Field1.asInteger := StrToInt(Copy(text,2,2));
Field2.asString := Copy(text,7,3);
Field3.asString := Copy(text,13,5);
Field4.asString := Copy(text,21,8);
TempTable.post;
end;
// Close the file for the last time
CloseFile(myFile);
end;您可以使用嵌入式引擎实现非常高的速度,几乎没有大小限制,但您的存储空间。例如,请参阅how fast we can add content to a database in our ORM:数据库文件中每秒大约130,000 / 150,000行,包括所有ORM编组。我还发现SQLite3生成的数据库文件比其他方法小得多。如果您希望快速检索任何字段,请不要忘记在插入行数据后在数据库中定义INDEXes (为了提高速度)。对于SQLite3,已经有一个ID/RowID整数主键可用,我想它映射了您的第一个数据字段。SQLite3已对此ID/RowID整数主键进行了索引。顺便说一下,我们的对象关系映射现在支持FireDAC / AnyDAC and its advanced Array DML feature。
发布于 2013-07-18 12:07:35
文本文件通常有一个非常小的缓冲区。考虑使用SetTextBuf function来提高您的性能。
var
myFile : TextFile;
text : string;
myFileBuffer: Array[1..32768] of byte;
begin
// Try to open the Test.txt file for writing to
AssignFile(myFile, 'Test.txt');
SetTextBuf(MyFile, myFileBuffer);
Reset(MyFile);
// Display the file contents
while not Eof(myFile) do
begin
ReadLn(myFile, text);
end;
// Close the file for the last time
CloseFile(myFile);
end;发布于 2013-07-18 16:24:17
除了前面提到的内容之外,我还会避免使用任何TTable组件。您最好使用TQuery类型的组件(取决于您正在使用的接入层)。就像这样:
qryImport.SQL := 'Insert Into MyTable Values (:Field1, :Field2, :Field3, :Field4);';
Procedure ImportRecord(Const pField1, pField2, pField3, pField4 : String);
Begin
qryImport.Close;
qryImport.Params[0].AsString := pField1;
qryImport.Params[1].AsString := pField2;`
qryImport.Params[2].AsString := pField3;
qryImport.Params[3].AsString := pField4;
qryImport.ExecSQL;
End;希望这能有所帮助。
https://stackoverflow.com/questions/17712813
复制相似问题