|
15番会議室「FAQ編纂委員会」に寄せられた「よくある質問の答え」
[Q]
ディレクトリ名をリネームしようと、Rename や、RenameFile を使ってもエ
ラーになります。ほかに方法はありますか?
[A]
変えようとする子ディレクトリーの親に、カラントディレクトリーを移動す
れば、問題のディレクトリーを、ファイルと同等なものとして扱え、Rename
や、RenameFile を使ってディレクトリー名をリネームできます。エラーとな
ったのは、カラントディレクトリーがそのディレクトリーだったためです。
以下の[例]では、変えようとする子ディレクトリーの親にカラントディレ
クトリーを移動して RenameFile や Rename を実行しています。しかし、親
でなくてもかまいません。要するに、カラントが、改名しようとするディレ
クトリー以外にあれば、それが異なるドライブ上であっても、大丈夫です。
◆また、FileListBox で、FileType プロパティの ftVolumeID を true にし
ておくと、ボリュームラベルが表示されるようになりますが、これを Rename
や RenameFile で変更することは、できません。残念!(出来そうでできな
い、第1弾)
[例]
フォームに DirectoryListBox1 と、適当なボタンを配置し、procRendir
あるいは procAssRendir を実行します。
IDE で実行する場合、
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
プロジェクトファイルの存在するディレクトリー名は変えないで下さい。終
了後プロジェクトの保存ができなくなります。
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
うっかりそうしてしまった場合は、ファイルマネージャなどで、元のディレ
クトリー名に直して下さい。ほかのディレクトリーで試すのが賢明です。
【注】ルートをリネームしようとした場合のエラー処理が抜けています。
{=========================================================}
procedure TForm1.procRendir;
var
i,iCount: integer;
OldDir,CurDir,NewDir,pDir
: string;
begin
iCount:=DirectoryListBox1.Items.Count;
if (iCount=0) or (DirectoryListBox1.SelCount=0) then exit;
for i:=0 to iCount-1 do
if DirectoryListBox1.Selected[i] then begin
OldDir:=DirectoryListBox1.Items[i];
{選択子ディレクトリー名(最末端のみ)が入っている}
break;
end;
CurDir:=DirectoryListBox1.Directory;
{フルパスの選択子ディレクトリー名}
pDir:=CurDir;
GetTailFromString(pDir,'\');
{pDirに選択子ディレクトリーの親ディレクトリー名が入る}
NewDir:='NewDir';
if not InputQuery('新ディレクトリー名',
'旧ディレクトリー名:'+OldDir+#13+
'新ディレクトリー名:',
NewDir) then exit;
pDir:=GetDirectory(pDir);{ルートの場合'\'添加}
ChDir(pDir); {親に移動}
DirectoryListBox1.Directory:=pDir;
{DirectoryListBox1も親に移動しておかないと
子ディレクトリー名変更後エラー}
{------------------------------------------}
if not RenameFile(OldDir,NewDir) then begin {ここです}
{------------------------------------------}
DirectoryListBox1.Directory:=CurDir;
{変更できなかったときは元に戻す}
ShowMessage('Cannot Rendir!');
end else
DirectoryListBox1.Directory:=
PutYenMark(pDir)+NewDir;
{変更できたらそのディレクトリーを表示}
end; {procRendir}
{=========================================================}
procedure TForm1.procAssRendir;
var
f: File;
i,iCount: integer;
OldDir,CurDir,NewDir,pDir
: string;
begin
iCount:=DirectoryListBox1.Items.Count;
if (iCount=0) or (DirectoryListBox1.SelCount=0) then exit;
for i:=0 to iCount-1 do
if DirectoryListBox1.Selected[i] then begin
OldDir:=DirectoryListBox1.Items[i];
{選択子ディレクトリー名(最末端のみ)が入っている}
break;
end;
CurDir:=DirectoryListBox1.Directory;
{フルパスの選択子ディレクトリー名}
pDir:=CurDir;
GetTailFromString(pDir,'\');
{pDirに選択子ディレクトリーの親ディレクトリー名が入る}
NewDir:='NewDir';
if not InputQuery('新ディレクトリー名',
'旧ディレクトリー名:'+OldDir+#13+
'新ディレクトリー名:',
NewDir) then exit;
pDir:=GetDirectory(pDir);{ルートの場合'\'添加}
ChDir(pDir); {親に移動}
DirectoryListBox1.Directory:=pDir;
{DirectoryListBox1も親に移動しておかないと
子ディレクトリー名変更後エラー}
{--------------------}
AssignFile(f,OldDir); {ここです}
Rename(f,NewDir);
{--------------------}
if not DirectoryExists(NewDir) then begin
DirectoryListBox1.Directory:=CurDir;
{変更できなかったときは元に戻す}
ShowMessage('Cannot Rendir!');
end else
DirectoryListBox1.Directory:=
PutYenMark(pDir)+NewDir;
{変更できたらそのディレクトリーを表示}
end; {procAssRendir}
{=========================================================}
function TForm1.GetDirectory(vDir: TFilename):TFilename;
var
PosY,Len
: integer;
begin
Result:=vDir;
Len:=Length(vDir);
if vDir[Len]='\' then begin
if (Len=3) and (UpCase(vDir[1]) in ['A'..'Z'])
and (vDir[2]=':') then
else Result:=Copy(vDir,1,Len-1);
end else begin
if (Len=2) and (UpCase(vDir[1]) in ['A'..'Z'])
and (vDir[2]=':') then
Result:=vDir+'\'
end;
end; {GetDirectory}
{=========================================================}
function TForm1.PutYenMark(vDir: TFilename): TFilename;
var
Len: integer;
begin
Len:=Length(vDir);
if vDir[Len]<>'\' then Result:=vDir+'\'
else Result:=vDir;
end; {PutYenMark}
{=========================================================}
function TForm1.GetTailFromString(var vStr: string; ch: char)
: string;
{vStr の末尾から ch までを返す。
vStr には残りの先頭が返される}
var
Len,PosC
: integer;
begin
Len:=Length(vStr);
PosC:=Len;
while (vStr[PosC]<>ch) and (PosC>0) do
dec(PosC);
if PosC=0 then begin
Result:=vStr; vStr:='';
end else begin
if PosC=Len then Result:=''
else
Result:=Copy(vStr,PosC+1,255);
vStr:=Copy(vStr,1,PosC-1);
end;
end; {GetTailFromString}
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum FDELPHIに寄せられる質問の中から、よくある質問への回答を FDELPHIのメンバーがまとめたものです。 したがって、これらの回答はボーランド株式会社がサポートする公式のものではなく、掲示されている内容についての問い合わせは受けられない場合があります。
Copyright 1996-1998 Delphi Users' ForumFAQ編纂委員会
|