どうも、今晩は。
少しだけお久しぶりです。
脇保です。
さて、もう夜中ですが、今日は土曜日です。
色々作業してました。
以下の続きをしていました。
Mac OS X Lzarusにて SJIS(Ansi)対応が難しい事について。
と、その続きの、
lazarus(delphi言語)にて、外部プログラムを呼び出す。
について、です。
Mac OS X Lzarusにて SJIS(Ansi)対応が難しい事について。
と、その続きの、
lazarus(delphi言語)にて、外部プログラムを呼び出す。
について、です。
で、大進展です。
sjis(Ansi)フォーマットの文章を、
自作ブログラムから開く事に成功しました。
作ってみた結果、これは大変便利ですね。
応用次第で色々なフォーマットに対応出来ます。
では、報告。
土曜日になり、
時間も出来たので色々いじりながら、
作業を開始しました。
どんな方法がいいか?
勿論、Linuxコマンドを呼び出して、
そこから変換してしまう方法です。
そこで、白羽の矢をたてたのが、nkfなるコマンド。
早速作業開始。
が、シェルコマンドを起動させる事が出来ない。
lazarus wikiのサンプルを良く見てみる。
・・・。
なるほど、オプションが必要な訳ね。
今度はオプションを指定して、無事シェルプログラムを起動、
ファイルを作業フォルダにコピー後、
ファイルを変換し、読み込む・・・、
のだが、ちっとも変換されない。
何故??
ここで大きく時間を取られるも、
試しに、シェルから、手打ちでコマンドを実行、
・・・しようとしたら、、、
そんなコマンド、macに入ってないよと怒られたTT。
そう、Macには、どうもnkfコマンドは標準では入っていないらしい。
そこで、apt-getで、取得しようとするも、
それも、、、入っていない。。。
更に考えてみると、使ってくれるだろうユーザーさんに、
このプログラムを実行する前に、
このシェルコマンドをインストールしてね、なんて、
さすがにそれは、回避すべきではなかろうか、とも思う訳で、
更には、その前にインストールプログラムもインストールしなくてはいけないという、
この不便さ・・・orz。
なので、有無を言わさずnkfコマンドは却下。
時間とられたぞ。
そこで、他のコマンドは無いか、ググってみる。
あるじゃないですか、iconvなるコマンドが。
基本的には、使い方はほぼ同じ。
変換元フォーマットと、変換先フォーマットを指定して、入力ファイルを指定、
パイプ処理でファイルを出力させれば、ok。
で、ここまで来て、piconvなる、
より良いコマンドがmacにあると判り、
こちらを使用する事で決定。
さて、実行。。。
しかし。。。
何度やっても、開けない。
ファイル自体は存在するものの、
空のファイルとして開かれる。
そこで、プログラム終了後、一時出力された、変換後ファイルを開いてみる。
問題なく、utf8に変換されていて、開く事が出来た。
なるほど、変換し終わる前にファイルをオープンしてたのね。
そこで、
sleepコマンドを使って、
sleep(100);
を実行、処理待ちをしてからファイルを開く。
問題なく開けた。
しかし、実際のプログラムでこれはマズい。
短いファイルなら良いが、でかいファイルを開いたらどうするのか?
TProcessを調べてみる。
すると、あるじゃないですか、runningなる、
bool値(boolean)の参照専用のものが。
早速、これを組んでみる。
最初は、notを前に入れてみたが、
こうした所、全く白紙のファイルがオープンされた。
処理が完了したら、True(真)を返すのね。
で、notを外して実行すると、、、
ぴたりと開けました(^^)。
ディスクに書き込む分、ちょっと処理は遅いし、
もうちょっとスマートな方法がありそうな気もするけど、
取り敢えず、まあ、良いかなと。
で、以下はそのサンプル。
//os: MacOSX10.9.2
//環境:Lazarus10.2.2
//日本語版WIndowsで作成された、sjisフォーマットの文章をMacで開く為の、
//Lazarus(Mac版)のサンプルコード
//TMemoとTButton、TOpenDialogコンポーネントを使用。
//ソースファイル ここから
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;
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;
//プロセスが完了したら、メモコンポーネントに、出力させたファイルを読み込む
if Process.Running then begin
Memo1.Lines.LoadFromFile( setfile );
end;
//作業フォルダが汚れない様に、読み込んだ一時ファイルを削除する
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.
//ソースファイルここまで