GNU/Linux >> Linux の 問題 >  >> Linux

C で Linux 上のファイルを移動する

ファイルの元の場所と新しい場所が同じファイルシステム上にある場合、「移動」は概念的に「名前の変更」と同じです。

#include <stdio.h>

int rename (const char *oldname, const char *newname)

C でファイルを移動する通常の方法は rename(2) を使用することですが、失敗することもあります。

rename(2) syscall を使用できない場合 (たとえば、ソースとターゲットが異なるファイルシステム上にあるため)、stat(2) を使用してソース ファイルのサイズ、パーミッション、およびその他のメタデータを照会する必要があります。 read(2)、write(2) (数キロバイトのバッファを使用)、open(2)、close(2) でループするデータと、chmod(2)、chown(2)、utime(2) を使用してメタデータをコピーします。 .また、getxattr(2)、setxattr(2)、listxattr(2) を使用して属性をコピーすることにも関心があるかもしれません。 David C. Rankin がコメントしているように、場合によっては sendfile(2) を使用することもできます。

また、ソースとターゲットが異なるファイルシステム上にある場合、移動をアトミックにして競合状態を回避する方法はありません (man ページによるとアトミックであるため、可能であれば rename(2) を使用することをお勧めします)。ソース ファイルは、移動操作中にいつでも (別のプロセスによって) 変更できます...

したがって、ファイルを移動する実用的な方法は、最初に rename(2) を実行してみて、それが EXDEV で失敗した場合です。 (oldpath の場合 と新しいパス マウントされた同じファイルシステム上にない場合)、バイトとメタデータをコピーする必要があります。いくつかのライブラリは、それを行う関数を提供します。 Qt QFile::rename.

Advanced Linux Programming を読み、syscalls(2) を参照してください (さらに、strace も試してください) いくつかの mv それが何をしているかを理解するためのコマンド)。その本は自由かつ合法的にダウンロードできます (そのため、Web 上でいくつかのコピーを見つけることができます)。

/bin/mv コマンド (mv(1) を参照) は、フリー ソフトウェアである GNU coreutils の一部です。そのソース コードを調べるか、strace(1) を使用してそのコマンドが何をするか (syscalls(2) に関して) を理解することができます。 sash や busybox などの一部のオープン ソース Unix シェルでは、mv シェル組み込みの可能性があります。 path_resolution(7) と glob(7) も参照してください。

微妙なケースもあります (別のプロセスまたは pthread が、同じファイルシステム、ディレクトリ、またはファイルに対して何らかのファイル操作を行っていると想像してください)。詳しくは、オペレーティング システムの教科書を読んでください。

ファイル名に tab などの奇妙な文字が含まれている場合、snprintf(3)、system(3)、mv(1) を組み合わせて使用​​するのは難しい場合があります。 または または改行、または最初の - で始まる . errno(3) を参照してください。


Linux
  1. Linuxターミナルでファイルの名前を変更します

  2. Linuxでmvなしでファイルを移動する

  3. Linux –すべてがファイルですか?

  1. Linuxでファイルを移動する方法

  2. Linuxでファイルの名前を変更するにはどうすればよいですか?

  3. Linux - ファイル名のスペースの置き換え

  1. Linuxファイルのアクセス許可について

  2. Linuxテールコマンド

  3. Linuxタッチコマンド