TSTRINGLISTに多くの文字列を追加する問題
-
19-09-2019 - |
質問
tstringlistに文字列を追加するのに問題があります。他の投稿を検索しましたが、これに対する答えが見つかりませんでした。
私がやろうとしているのは、大量の文字列をTStringList(14000以上)に追加することですが、その過程のどこかでeaccessviolationを取得します。これが私が使用しているコードです:
procedure TForm1.FormCreate(Sender: TObject);
begin
List := TStringList.Create;
List.Duplicates := dupAccept;
end;
procedure TForm1.ButtonStartClick(Sender: TObject);
begin
List.Clear;
List.Add('125-AMPLE');
List.Add('TCUMSON');
List.Add('ATLV 4300');
List.Add('150T-15');
List.Add('TDL-08ZE');
List.Add('RT20L');
List.Add('SIN LINEA');
List.Add('TIARA');
List.Add('FL200ZK1');
List.Add('FL250ZK1');
List.Add('SIN LINEA');
List.Add('CENTAURO-70 S.P.');
List.Add('CORSADO');
{ This list continues to about 14000 strings...}
List.Add('VOSJOD 2');
List.Add('Z 125');
List.Add('ZUMY');
List.Add('NEW AGE 125');
List.Add('SIN LINEA');
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(List);
end;
¿このコードの何が問題になっていますか?リストには重複した文字列が含まれているので、設定します Duplicates
プロパティへ dupAccept
. 。使用してリストをロードすることができました LoadFromFile
, 、しかし、アプリケーションの外にテキストファイルを持ちたくありません。
私はあなたが私を助けることができることを願っています!!!さらに情報が必要かどうか教えてください。
どうもありがとうございました。本当に感謝しています。
解決
外部ファイルを使用するための提案は、ここでマークに記載されています。ただし、投稿は、外部ファイルを持たないという欲求を示しています。次に、ファイルをリソースとして実行可能ファイルにリンクすることをお勧めします。これらの手順に従って簡単にこれを行うことができます。
すべての文字列をstringdata.txt(または選択した名前)というテキストファイルに入れます。次に、選択した名前の.rcファイルを作成し、次の名前を入力します(String_Dataは、選択した任意の識別子にすることができます):
STRING_DATA RCDATA "stringdata.txt"
.rcから.resファイルを作成します:
BRCC32 <name of rc>.rc
次に、このファイルをソースコードから参照します。次の場所をユニットに配置します。
{$R <name of res>.res}
ファイルストリームからロードする代わりに、リソースストリームからロードします。
StringData := TResourceStream.Create(HInstance, 'STRING_DATA', RT_RCDATA);
try
List.LoadFromStream(StringData);
finally
StringData.Free;
end;
コマンドラインの自動化されたビルドを行う場合は、.RCファイルをソース制御下に保持し、ビルドプロセス中に.resをビルドすることをお勧めします。これにより、StringData.txtファイルをソースコントロールの下に保持することもでき、.txtファイルが変更されるたびに.resファイルを明示的にビルドすることなく、次のビルドで編集が自動的にキャッチされます。
他のヒント
どのDelphiバージョンを使用していますか?一部の古いバージョンには、メモリマネージャーにバグがあり、アレイを大きすぎるサイズに再配置しようとするときにアクセス違反を引き起こす可能性があります。
追加してみてください fastmm4 古いメモリマネージャーを置き換え、それが役立つかどうかを確認するためのプロジェクトに。
また、おそらくリストを外部ファイルに保持する方が良いでしょう。はい、それは別のファイルですが、プログラム全体を再コンパイルすることなくリストを変更できることも意味します。これにより、更新の作成(および配布)も簡単になります。
メイソンはおそらくAVの原因に適しています。これは、成長する非常に大きな配列です。
サイドノートでは、StringListでこのような長い処理を行う場合、更新イベントの発射を避けるためにBeginUpDate/EndupDateでそれを囲むことをお勧めします。
あなたが今何も持っていなくても、それらは後で追加され、問題が発生する可能性があります。
リストを作成した直後に、追加リストを設定します。または、リストをRCファイル(プロジェクトの名前以外の名前)に配置し、プロジェクトに追加します。これはアプリケーションにコンパイルされますが、リストを作成するための実行可能コードは含まれません。
また、14,000回のライン手順を備えたコンパイラの完全性についても心配します。人々は、合理的なものを超えてコンパイラをさまざまな方法で破る他のケースを見つけました。
また、ThashedStringListを試してみて、Speed Boostが表示される可能性があります(この関数ではありませんが)が表示されますが、ADDメソッドがまったく異なるかどうかはわかりません。
コードの代わりに次のものを使用して、文字列をstringlistに追加してみてください
var
str:文字列;
始める
str:= '125-ample' +#13#10;
str:= str + 'tcumson' +#13#10;
str:= str + 'atlv 4300' +#13#10;
str:= str + '150t-15' +#13#10;
................
list.text:= str;
終わり;