掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.24824

ファイルのコピー
投稿者---べた(2005/12/15 12:50:10)


ファイルのコピーについてなのですが、
ファイル1の内容をファイル2にコピーしようとしています。
実際、ファイルをコピーする関数はないので、自作すること
になりますが、その時、どのような方法がよいのでしょうか。

1.
 ファイル1とファイル2をオープンする。
 ファイル1の内容を1行ずつ読み込み、ファイル2に書き込む。
 ファイル1とファイル2をクローズする。

2.system関数を使い、UNIXのcpコマンドを実行し、コピーする。
 fprintf(cmd,"%s %s %s","mv",ファイル1,ファイル2);
  if (system(cmd) != OK)
  {
     エラー処理
  }


どのような方法がよいのでしょうか。

環境
Solaris
UNIX-C
gcc
です。



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ファイルのコピー 24825 RAPT 2005/12/15 13:08:08
<子記事> Re:ファイルのコピー 24834 nop 2005/12/15 21:49:22
<子記事> Re:ファイルのコピー 24848 かずま 2005/12/17 14:10:03


No.24825

Re:ファイルのコピー
投稿者---RAPT(2005/12/15 13:08:08)


どちらでもお好きなほうを。

> fprintf(cmd,"%s %s %s","mv",ファイル1,ファイル2);
fprintf() は、第一引数にストリームを指定するものなので使用できません。
# しかも、cpじゃなく、mvになってるが。

char cmd[BUFSIZ] = {0};
sprintf(cmd, "cp %s %s", "file_from", "file_to");
のようにします。



この投稿にコメントする

削除パスワード

No.24827

Re:ファイルのコピー
投稿者---Craft(2005/12/15 13:35:00)


>どちらでもお好きなほうを。

system()だとファイルアクセスでエラーがあったときの原因を拾うのが
ほとんど不可能なので、ファイルアクセス関数使った方が確実ではありますね。

systemで渡す文字列にワイルドカード文字がわたった場合って、
どうなるんでしたっけ?
<いまテストできる状況にないので
シェルで実行だから展開するんだったかな?忘れてしまった。


この投稿にコメントする

削除パスワード

No.24830

Re:ファイルのコピー
投稿者---RAPT(2005/12/15 18:59:32)


>system()だとファイルアクセスでエラーがあったときの原因を拾うのが
>ほとんど不可能なので、ファイルアクセス関数使った方が確実ではありますね。
Yes.
その代わり、仮にリダイレクトの処理などもシェルに依存できるので
楽は楽ですね。

>systemで渡す文字列にワイルドカード文字がわたった場合って、
>どうなるんでしたっけ?
シェルにより、展開されます。




この投稿にコメントする

削除パスワード

No.24835

Re:ファイルのコピー
投稿者---べた(2005/12/16 12:05:41)


ありがとうございます。

ファイルアクセス関数とは、fopen、fcloseと言った類
のものですか。
どの関数でしょうか。
できれば使い方などを教えていただきたいのですが。



この投稿にコメントする

削除パスワード

No.24838

Re:ファイルのコピー
投稿者---べた(2005/12/16 18:07:17)


すみません。

変な質問をしました。
内容をせずに質問してすみません。

ファイルアクセス関数は、読んで字のごとくファイルにアクセスする
関数ですから、皆さんが言われているのは、1番ということですね。


この投稿にコメントする

削除パスワード

No.24846

Re:ファイルのコピー
投稿者---べた(2005/12/17 01:19:43)


>>system()だとファイルアクセスでエラーがあったときの原因を拾うのが
>>ほとんど不可能なので、ファイルアクセス関数使った方が確実ではありますね。
>Yes.
>その代わり、仮にリダイレクトの処理などもシェルに依存できるので
>楽は楽ですね。
どういうことでしょうか。


この投稿にコメントする

削除パスワード

No.24834

Re:ファイルのコピー
投稿者---nop(2005/12/15 21:49:22)


>1.
> ファイル1とファイル2をオープンする。
> ファイル1の内容を1行ずつ読み込み、ファイル2に書き込む。
> ファイル1とファイル2をクローズする。
>2.system関数を使い、UNIXのcpコマンドを実行し、コピーする。

私は「2」をお勧め。
理由は、単純に楽だから。
コマンドの呼び出し部分のデバッグのみで良いのも魅力です。


# 後は、好みの問題です。


この投稿にコメントする

削除パスワード

No.24848

Re:ファイルのコピー
投稿者---かずま(2005/12/17 14:10:03)


UNIX なら、open/read/write/close が普通でしょう。

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fd0, fd1, n;  char buf[4096];

    if (argc != 3) return printf("usage: %s src dst\n", *argv), 3;
    fd0 = open(argv[1], O_RDONLY);
    if (fd0 < 0) return printf("can't oepn %s\n", argv[1]), 1;
    fd1 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd1 < 0) return printf("can't create %s\n", argv[2]), 2;

    while ((n = read(fd0, buf, sizeof buf)) > 0)
        write(fd1, buf, n);
    close(fd0);
    close(fd1);
    return 0;
}

----------------------------------------------------------------------
mmap を使う方法もあります。
ここでは write 一発の例しか挙げませんが、ファイルのサイズが、使用
可能なメモリー空間より大きい場合のことを考えて、mmap に offset を
指定し、複数回の write になるのが本当でしょう。

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
    int fd0, fd1, r = 0;  char *p;  size_t size;  struct stat buf;

    if (argc != 3) return printf("usage: %s src dst\n", *argv), 3;
    fd0 = open(argv[1], O_RDONLY);
    if (fd0 < 0) return printf("can't oepn %s\n", argv[1]), 1;
    fd1 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd1 < 0) return printf("can't create %s\n", argv[2]), 2;

    fstat(fd0, &buf);
    size = buf.st_size;
    if (size != buf.st_size) return puts("file too long"), 4;

    p = mmap(0, size, PROT_READ, MAP_SHARED, fd0, 0);
    if (p == MAP_FAILED) {
        puts("mmap failed");
        r = 5;
    } else {
        write(fd1, p, size);
        munmap(p, size);
    }
    close(fd0);
    close(fd1);
    return r;
}

----------------------------------------------------------------------
単純なファイルコピーに fopen/fclose を使うと、バッファリングのための
無駄なコピーが発生します。




この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧