サーバレス練習帳

着眼大局着手小局

【Delphi FMX】Drag&Dropでファイルを受け取る

(1) まずはDrag&Dropの設定
f:id:urbanplanner:20180820125432p:plain

これでパス 及び ファイル名を取得できる。
ListBox1に落とさせる場合、「AlloDrag」をTrueにしておくことが必要です。

procedure TForm1.ListBox1DragDrop(Sender: TObject;
  const [Ref] Data: TDragObject; const [Ref] Point: TPointF);
begin
  Label1.Text:=Data.Files[0];
end;


(2) ファイルの読み取り
最近はReadlnは流行っていないらしい。
serverless.hateblo.jp

が、コチラのリンクの3つの方式を比較すると、「ロックされたファイルの読込」可能なAssignFileで良いんじゃないか?と思う。
qiita.com

どうせ、1行目の取得と、ファイルのコピーしかしないしね。

古いページですが、AssignFileの読み取りは、こんこページが役に立つ。
http://www.geocities.co.jp/SiliconValley-SanJose/2560/delphi4/pascal/File.htm

・・・ダメだ!
AssignFileはUTF8を読めないっぽい!
(上記のリンクの下の方の比較表より)

では、TStreamReaderだな。
上記リンクより引用したTStreamReaderの使い方です。

  try
    sr := TStreamReader.Create(filename);
    str := sr.ReadToEnd();       //全文string読込(ここでも文字コードの例外が飛ぶ可能性あり)
    while not sr.EndOfStream do  //(ここでも文字コードの例外が飛ぶ可能性あり)
    begin
      line := sr.ReadLine;     //一行読込
    end;
  except
    on e: Exception do
    begin
      ShowMessage('ERROR:' + e.Message);
      exit;
    end;
  end;
  sr.Free();
  sl := TStringList.Create();
  sl.Text := str;            //全文TStringList読込はないのでstringを代入


ちなみに、1行目(ヘッダー行)だけ読み取りたいのなら、以下の様な感じです。

procedure TForm1.ListBox1DragDrop(Sender: TObject;
  const [Ref] Data: TDragObject; const [Ref] Point: TPointF);
var
  SR:TStreamReader;
  strHeaderAll:string;
  intColumnCount:integer;
  rcTableColumn:TTableColumnRec;
  SL:TStringList;
begin
  Label1.Text:=Data.Files[0];
  lsTableColumn:=TList<TTableColumnRec>.Create;
  //ヘッダー(1行目)の読み込み
  try
    intColumnCount:=0;
    SR := TStreamReader.Create(Data.Files[0]);
    SL := TStringList.Create();
    strHeaderAll := SR.ReadLine;
    while Pos(',',strHeaderAll) <> 0 do
    begin
      rcTableColumn.id:=intColumnCount;
      rcTableColumn.strColumnName:=Copy(strHeaderAll,1,Pos(',',strHeaderAll)-1);
      rcTableColumn.strColumnType:='';
      rcTableColumn.strElementId:='';
      lsTableColumn.Add(rcTableColumn);
      SL.Add(rcTableColumn.strColumnName);
      //FMX.Dialogs.ShowMessage(rcTableColumn.strColumnName);
      Delete(strHeaderAll,1,Pos(',',strHeaderAll));
      intColumnCount:=intColumnCount+1;
    end;
    SL.SaveToFile('./Columns.csv', TEncoding.UTF8);
  except
    on e: Exception do
    begin
      ShowMessage('ERROR:' + e.Message);
      exit;
    end;
  end;
  SL.Free();
  SR.Free();
  //ヘッダー(1行目)の書き込み
end;


(3) ファイルコピー
これは、このまま使えそう。
「System.IOUtils」を使う模様。
www.gesource.jp