MacOSXのLazarusプログラムから、Linuxコマンドでsjisファイルを変換し、プログラムから開く。 – Information Teaching Service 雄飛

MacOSXのLazarusプログラムから、Linuxコマンドでsjisファイルを変換し、プログラムから開く。

どうも、今晩は。
少しだけお久しぶりです。
脇保です。
さて、もう夜中ですが、今日は土曜日です。
色々作業してました。
で、大進展です。
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.

//ソースファイルここまで

コメントをどうぞ

メールアドレスが公開されることはありません。 が付いている欄は必須項目です