今晩は、脇保です。
さて、ブログ更新です。
前回の、sjis変換プログラムのサンプルに、
不具合がありましたので、その修正をしていました。
前回のブログ
先ず、こちらの思い違いがあったようで。
「Process.Running」
これは、確かにプロセスが終了するとTrueを返しますが、
そこには、今回の場合、書き込みのタイムラグが発生していて。
その結果、ファイル出力の途中でオープンされたりして、
中途半端なファイルを開いてしまう。
という、問題に気づきました。
そこで、プロセス実行中にカウントを取り、
それをsleepに入れるという、
代替え処置をとりました。
ただ、この方式だと、
個別のディスクドライブへの書き込み速度によって、
成功する場合と失敗する場合が、
出る恐れがあります。
最終的には、直接変数にパイプをつなぐ方法を探すか、
何らかの方法で、ファイルが処理終了された事を確認して、
それから処理に移る、という方法をとると思います。
以下が、その(応急での)変更部分になります。
//変更部分ここから
i := 0;
while Process.Active do begin
inc(i);
end;
i := i div 1000;
showmessage(inttostr(i));
sleep(i);
//ここまで
//ソース全体 ここから
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Process;
//usesにProcessを追加するのを忘れずに。
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var
Process:TProcess;
setFile: string;
i:integer;
i:integer;
begin
if not OpenDialog1.Execute then
exit;
setfile := ExtractFilePath( Paramstr(0) ) + ‘tmp.txt’;
//TProcessを宣言
Process := TProcess.Create(nil);
//オプションを指定して、パイプライン処理とファイル出力を有効にする
Process.Options := [poUsePipes, poStderrToOutPut];
//コマンドラインを指定し、シェルコマンドのpiconvを呼び出し、sjisファイルを、utf8に変換させる。
//オプションを指定し、入力ファイルを設定、パイプ処理を行い、ファイルを出力させる
Process.Commandline := ‘sh -c “piconv -f sjis -t utf8 ‘ + OpenDialog1.FileName + ‘ > ‘ + setfile + ‘”‘;
//プロセスを実行
Process.Execute;
//プロセスをカウントし、カウントされた秒数、プログラムをスリープさせる。
i := 0;
while Process.Active do begin
inc(i);
end;
i := i div 1000;
showmessage(inttostr(i));
sleep(i);
//ファイルを読み込む
Memo1.Lines.LoadFromFile( setfile );
//作業フォルダが汚れない様に、読み込んだ一時ファイルを削除する
Process.Commandline := ‘sh -c “rm ‘ + setfile + ‘”‘;
Process.Execute;
//プロセスを解放する
Process.Free;
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
//そのままプログラムを閉じるとフリーズを起こすので、使ったメモコンポーネントを解放させる
Memo1.Clear;
Memo1.Free;
end;
end.
//ソースファイルここまで