ファイルへ書き込むには?

解決


さばたん  2003-01-29 02:00:39  No: 2696

こんにちは。
ファイルを新規で作成し、
そこに文字(Str)を書き出そうとしています。

procedure TForm1.Button1Click(Sender: TObject);
var
  FileName,Str: String;
  FileHandle,Size: Integer;
begin
  Str := 'abcdefg';
  FileHandle := FileCreate('C:\test.txt');
  FileName := '???';  //←何を入れる?
//FileHandle := FileOpen(FileName,fmOpenReadWrite);
  Size := GetFileSize(FileHandle, nil);
  FileWrite(FileHandle,FileName,Size);
                       ~~~??~~~
end;

ヘルプなどを見たのですが、書き込むことができません。
Str の"abcdefg"という文字を書き込むにはどのようにすればよいのでしょうか?

お分かりの方がいましたら、宜しくお願いします。


たかみちえ  URL  2003-01-29 02:54:00  No: 2697

FileCloseを忘れてますよ?

  でも、それでもうまくは書き込めないはずですね、
FileWriteの第二引数のBufferの使い方が間違っています。

  FileWriteなどは使わないのではっきりとはいえませんけど、
Bufferには、ファイルに書き込む内容、第三引数にはそのサイズを指定しないといけません。
GetFileSizeを使った時点では、ファイルは空っぽですね?

  ところで、TStringListのSaveToFileを使ったほうが早いような気がします。
この方法を覚えておいても損はないと思いますけど。


にしの  2003-01-29 03:28:05  No: 2698

FileCreateするとファイルハンドルが返されます。
この時点では、ファイルは「閉じていません」
再度開く必要はありません(閉じるまで開けません)。

サイズは、書き込みたい文字列のサイズです。

Bufferは、
PChar(Str)^
と指定すればよいです。
array of charやarray of byteならば、その配列の最初の要素を指定します。
# 指定は、ポインタではありません


さばたん  2003-01-29 05:58:30  No: 2699

たかみちえさん、にしのさん、ありがとうございます。

procedure TForm1.Button1Click(Sender: TObject);
var
  FileHandle: Integer;
  Str: String;
begin
  FileHandle := 0;
  try
    FileHandle := FileCreate('C:\test.bat');  //ファイル作成
    Str := 'ipconfig/all > C:\test.txt';
    FileWrite(FileHandle,PChar(Str)^,(Length(Str)));
  //Sleep(100);
    ShellExecute(FileHandle, 'open', 'C:\test.bat', nil, nil, SW_SHOW);  //起動
  finally
    FileClose(FileHandle);      //ファイル閉じる
    //DeleteFile('C:\test.bat');  //ファイル削除
  end;
end;

test.batを作成して起動させ、'test.txt'を作り、
test.batを削除しようとしているのですが、'test.txt'が作成されません。
test.batは作成され、手動で起動させるとちゃんと'test.txt'を作成します。
test.batが作成される前に起動させているとかなのでしょうか?

どうぞよろしくお願いします。


たかみちえ  URL  2003-01-29 06:59:23  No: 2700

コードの実行速度が速すぎて、バッチファイルがまだ動作中なのでは?
バッチファイルの実行終了を待つようにタイミングを合わせないといけなさそうです。

  バッチファイルに使えるかどうかは試したことないですけど、
うちの"おんぷ村倉庫"にある、"stdFiles"ユニットの"RunAs"関数を試してみてください。
  バッチファイルならば、第四引数のWaitFlagに、wfWaitFullを指定すれば、起動したプロセスが終了するまで待ってから処理を続けることができます。
  いちおうこれでコンソールアプリケーションの実行待ちには成功しています。


たかみちえ  URL  2003-01-29 07:03:16  No: 2701

あ、そうだ…。
  バッチファイルは自己消滅させることもできるそうです。
バッチファイル入門(http://www25.cds.ne.jp/~kamiken/bach/bach.html)

  まあ、その後の動作に支障をきたすと思うので、どちらにしても終了待ちをしたほうがいいとは思いますけど…。


にしの  2003-01-29 09:20:29  No: 2702

.batは、openするものではありませんよ。
cmd(もしくはcommand)が、.batを起動します。
openの対象はcmd(もしくはcommand)となります。
cmd(もしくはcommand)のヘルプや引数の説明を見てください。


さばたん  2003-01-29 19:27:54  No: 2703

たかみちえさん、にしのさん、ありがとうございます。

    ShellExecute(FileHandle, 'open', 'C:\test.bat', nil, nil, SW_SHOW);  //起動
の部分を
    RunAs('C:\test.bat','ipconfig/all > C:\test.txt',SW_SHOW,wfWaitFull);
    ShellExecute(FileHandle, 'open', 'C:\WINNT\system32\CMD.exe ipconfig/all > C:\test.txt', nil, nil, SW_SHOW);
としてみたのですが、'test.txt'が作成されません。
    ShellExecute(FileHandle, 'open', 'C:\WINNT\system32\CMD.exe', nil, nil, SW_SHOW);
とした場合、test.batは作成され、Command Prompt が起動したままになります。
Command Prompt に'ipconfig/all > C:\test.txt'を渡せばよいのでしょうか?
(そうならば、それはどのようにやるのでしょうか?)

宜しくお願いします。


にしの  2003-01-29 20:04:18  No: 2704

cmdの引数について調べましたか?
そう書いたつもりなのですが。

コマンドプロンプト上で、
cmd /?
と実行すると引数の使い方が出ます。
これを見ると、/Cオプションが必要だということが解ると思います。


にしの  2003-01-29 20:10:40  No: 2705

もう一つ、もしかしたら、DOSのリダイレクション機能は使えないのかもしれません。
前に同じようなことで悩んだような気がします。
# あやふやですみません

CreateProcessで起動し、その標準出力ハンドルから読みとれば可能です。


にしの  2003-01-29 20:26:53  No: 2706

リダイレクション使えますね。
ShellExecute(0, 'open', 'C:\Windows\system32\cmd.exe', '/C ipconfig/all > test.txt', nil, SW_SHOW);
ですね。
ただし、ipconfigがどのくらいで終わるかはわかりませんよ。
ShellExecuteは、起動できたら(終了を待たずに)次の処理に移ります。
ご注意を。


さばたん  2003-01-29 22:06:16  No: 2707

にしのさん、ありがとうございます。

出来ました!
.batを作る処理も省けました。
DOSコマンドだったのですね (^-^;;
DOSはあまり触ったことがなかったのですが
これを機に勉強してみようと思います。

> ただし、ipconfigがどのくらいで終わるかはわかりませんよ。
> ShellExecuteは、起動できたら(終了を待たずに)次の処理に移ります。
> ご注意を。
実行したところ影響はなさそうなのですがもう少し検証してみます。

大変勉強になりました!
たかみちえさん、にしのさん、ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加