複製檔案

說明:這個程式的目的是示範複製檔案的功能,在程式設計層面可以學習到檔案的處理,基本的流程是開啟檔案、對檔案進行讀取或寫入的動作、最後不再存取檔案時則關閉檔案。
  • 開啟檔案(並指定開啟檔案的權限模式): open()
  • 讀取檔案: read()
  • 寫入檔案: write()
  • 關閉檔案: close()
程式碼路徑:tlpi-dist/fileio/copy.c
Listing 4-1: copy.c
1
/*************************************************************************\
2
* Copyright (C) Michael Kerrisk, 2022. *
3
* *
4
* This program is free software. You may use, modify, and redistribute it *
5
* under the terms of the GNU General Public License as published by the *
6
* Free Software Foundation, either version 3 or (at your option) any *
7
* later version. This program is distributed without any warranty. See *
8
* the file COPYING.gpl-v3 for details. *
9
\*************************************************************************/
10
11
/* Listing 4-1 */
12
13
/* copy.c
14
將 argv[1] 指名的檔案複製到 argv[2] 指名的新檔案
15
*/
16
#include <sys/stat.h>
17
#include <fcntl.h>
18
#include "tlpi_hdr.h"
19
20
#ifndef BUF_SIZE /* 在 cc 編譯時,可以帶入編譯參數,例如:使用 "-D BUF_SIZE=512" 的方式來以 512 複蓋這裡的定義值 1024 */
21
#define BUF_SIZE 1024
22
#endif
23
24
int
25
main(int argc, char *argv[])
26
{
27
int inputFd, outputFd, openFlags;
28
mode_t filePerms;
29
ssize_t numRead;
30
char buf[BUF_SIZE];
31
32
if (argc != 3 || strcmp(argv[1], "--help") == 0)
33
usageErr("%s old-file new-file\n", argv[0]);
34
35
/* 開啟檔案做為讀取輸入與寫入輸出 */
36
37
/* 開啟要複製的檔案來源,以唯讀模式開啟 */
38
inputFd = open(argv[1], O_RDONLY);
39
if (inputFd == -1)
40
errExit("opening file %s", argv[1]);
41
42
openFlags = O_CREAT | O_WRONLY | O_TRUNC;
43
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
44
S_IROTH | S_IWOTH; /* rw-rw-rw- */
45
46
/* 開啟要複製的檔案目的,需要能夠寫入 */
47
outputFd = open(argv[2], openFlags, filePerms);
48
if (outputFd == -1)
49
errExit("opening file %s", argv[2]);
50
51
/* 持續複製資料,直到遇到檔案結尾或是發生錯誤為止 */
52
while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0)
53
if (write(outputFd, buf, numRead) != numRead)
54
fatal("write() returned error or partial write occurred");
55
56
if (numRead == -1)
57
errExit("read");
58
59
if (close(inputFd) == -1)
60
errExit("close input");
61
62
if (close(outputFd) == -1)
63
errExit("close output");
64
65
exit(EXIT_SUCCESS);
66
}
編譯程式:
tlpi-dist/fileio$ gcc copy.c ../libtlpi.a -o copy -I ../lib
執行程式:測試複製檔案 copy.c 到 copy1.c。
$ ./copy copy.c copy1.c
如果想在編譯時指定 BUF_SIZE,可以用 -D 編譯參數定義 BUF_SIZE 的數值:
tlpi-dist/fileio$ gcc copy.c ../libtlpi.a -o copy -I ../lib -DBUF_SIZE=2048