linux----文件访问(c语言)

linux文件访问相关函数

  1. 打开文件函数 - open
    • 函数原型int open(const char *pathname, int flags, mode_t mode);
    • 参数说明
      • pathname:这是要打开的文件的路径名,可以是绝对路径或者相对路径。例如,"/home/user/file.txt"或者"./data.dat"
      • flags:用于指定打开文件的方式,常见的标志有:
        • O_RDONLY:以只读方式打开文件。
        • O_WRONLY:以只写方式打开文件。
        • O_RDWR:以可读可写方式打开文件。
        • O_CREAT:如果文件不存在,则创建文件。通常和mode参数一起使用。
        • O_APPEND:以追加方式打开文件,写入的数据会添加在文件末尾。
      • mode:当使用O_CREAT标志创建文件时,这个参数用于指定文件的权限。它是一个八进制数,例如0644表示所有者有读写权限,所属组和其他用户有读权限。
    • 返回值
      • 成功时返回一个非负整数,这个整数是文件描述符(File Descriptor)。文件描述符用于后续对文件的读写等操作。例如,012分别是标准输入、标准输出和标准错误输出的文件描述符,而新打开的文件描述符通常是大于等于3的整数。
      • 失败时返回-1,并且会设置errno来指示错误原因,常见的错误原因可能是文件不存在、权限不足等。可以通过perror函数来打印错误信息。
    • 示例代码
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main() {
    int fd;
    // 以只读方式打开文件,如果文件不存在则返回错误
    fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
       perror("打开文件失败");
       return 1;
    }
    // 在这里可以进行文件的读取操作
    // 关闭文件
    if (close(fd) == -1) {
       perror("关闭文件失败");
       return 1;
    }
    return 0;
}
  1. 读取文件函数 - read
    • 函数原型ssize_t read(int fd, void *buf, size_t count);
    • 参数说明
      • fd:这是之前通过open函数打开文件得到的文件描述符。
      • buf:这是一个指向缓冲区的指针,用于存储读取到的文件内容。缓冲区的大小应该足够容纳要读取的数据。例如,可以定义一个字符数组char buffer[1024];来作为缓冲区。
      • count:这是要读取的字节数。例如,如果count10,则最多读取10个字节的文件内容。
    • 返回值
      • 成功时返回实际读取到的字节数。如果返回值小于count,可能是已经到达文件末尾或者被信号中断等原因。例如,返回0表示已经到达文件末尾。
      • 失败时返回-1,并且会设置errno来指示错误原因,常见的错误原因可能是文件描述符无效、权限不足等。
    • 示例代码(续接上面open函数的示例)
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main() {
    int fd;
    char buffer[1024];
    ssize_t num_read;
    // 以只读方式打开文件,如果文件不存在则返回错误
    fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
       perror("打开文件失败");
       return 1;
    }
    // 读取文件内容
    num_read = read(fd, buffer, sizeof(buffer));
    if (num_read == -1) {
       perror("读取文件失败");
       close(fd);
       return 1;
    } else if (num_read == 0) {
       printf("文件为空。\n");
    } else {
       buffer[num_read] = '\0';
       printf("读取到的内容:%s", buffer);
    }
    // 关闭文件
    if (close(fd) == -1) {
       perror("关闭文件失败");
       return 1;
    }
    return 0;
}
  1. 写入文件函数 - write
    • 函数原型ssize_t write(int fd, const void *buf, size_t count);
    • 参数说明
      • fd:文件描述符,和read函数中的fd类似,是通过open函数打开文件得到的。
      • buf:这是一个指向包含要写入数据的缓冲区的指针。例如,如果要写入一个字符串,可以定义char data[] = "Hello, World!";,然后将data作为buf参数。
      • count:这是要写入的字节数。例如,对于上面的字符串datacount可以是strlen(data)
    • 返回值
      • 成功时返回实际写入的字节数。如果返回值小于count,可能是磁盘空间不足、被信号中断等原因。
      • 失败时返回-1,并且会设置errno来指示错误原因,常见的错误原因可能是文件描述符无效、权限不足等。
    • 示例代码(写入一个新文件)
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main() {
    int fd;
    char data[] = "这是写入文件的测试内容。";
    // 以只写方式打开文件,如果文件不存在则创建文件
    fd = open("new_file.txt", O_WRONLY | O_CREAT, 0644);
    if (fd == -1) {
       perror("打开文件失败");
       return 1;
    }
    // 写入文件内容
    ssize_t num_written = write(fd, data, strlen(data));
    if (num_written == -1) {
       perror("写入文件失败");
       close(fd);
       return 1;
    }
    printf("写入了 %zd 个字节。\n", num_written);
    // 关闭文件
    if (close(fd) == -1) {
       perror("关闭文件失败");
       return 1;
    }
    return 0;
}
  1. 关闭文件函数 - close
    • 函数原型int close(int fd);
    • 参数说明
      • fd:这是要关闭的文件的文件描述符,是之前通过open函数打开文件得到的。
    • 返回值
      • 成功时返回0
      • 失败时返回-1,并且会设置errno来指示错误原因,常见的错误原因可能是文件描述符无效等。
    • 重要性
      • 关闭文件是一个重要的操作,它可以释放文件描述符资源,确保数据的完整性。如果不关闭文件,可能会导致文件损坏、资源泄漏等问题。例如,在写入文件后,如果没有正确关闭文件,数据可能没有完全写入磁盘,导致数据丢失。
  2. 文件打开与创建相关函数
    • open()函数
      • 功能:用于打开或创建文件。它是最基本的文件操作函数之一。
      • 参数
        • pathname:文件路径名,如"/home/user/documents/file.txt"。可以是绝对路径或相对路径。
        • flags:指定文件打开方式。例如,O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写)。还有其他一些标志,如O_CREAT(若文件不存在则创建)、O_APPEND(追加模式打开)等。
        • mode:当使用O_CREAT标志时,用于指定新创建文件的权限,如0644(所有者读写,组和其他用户只读)。
      • 返回值 :成功返回文件描述符(非负整数),失败返回 - 1,并设置errno
    • creat()函数
      • 功能 :创建一个新文件。它等效于open(pathname, O_WRONLY|O_CREAT|O_TRUNC, mode)
      • 参数
        • pathname:文件路径。
        • mode:文件权限模式。
      • 返回值 :成功返回文件描述符,失败返回 - 1。不过在现代Linux编程中,open()函数使用更广泛,因为它功能更灵活。
  3. 文件读取相关函数
    • read()函数
      • 功能:从打开的文件中读取数据。
      • 参数
        • fd:文件描述符,由open()等函数返回。
        • buf:指向存储读取数据的缓冲区的指针,例如char buffer[1024];
        • count:希望读取的字节数。
      • 返回值 :成功时返回实际读取的字节数。如果返回0,表示已读到文件末尾;返回 - 1表示出错,同时设置errno
    • pread()函数
      • 功能:从指定文件偏移量处读取数据,读取操作不会改变文件偏移量。
      • 参数
        • fd:文件描述符。
        • buf:缓冲区指针。
        • count:读取字节数。
        • offset:文件中的偏移量,从该位置开始读取。
      • 返回值 :和read()函数类似,成功返回实际读取字节数,0表示文件末尾, - 1表示出错。
  4. 文件写入相关函数
    • write()函数
      • 功能:将数据写入打开的文件。
      • 参数
        • fd:文件描述符。
        • buf:指向包含要写入数据的缓冲区的指针。
        • count:要写入的字节数。
      • 返回值 :成功时返回实际写入的字节数,可能小于count(如磁盘空间不足);返回 - 1表示出错,同时设置errno
    • pwrite()函数
      • 功能:在指定文件偏移量处写入数据,写入操作不会改变文件偏移量。
      • 参数
        • fd:文件描述符。
        • buf:包含要写入数据的缓冲区指针。
        • count:写入字节数。
        • offset:文件中的偏移量,在该位置写入。
      • 返回值 :和write()函数类似,成功返回实际写入字节数, - 1表示出错。
  5. 文件定位相关函数
    • lseek()函数
      • 功能:移动文件读写指针的位置,用于在文件中随机访问。
      • 参数
        • fd:文件描述符。
        • offset:偏移量,正数表示向文件尾方向移动,负数表示向文件头方向移动。
        • whence:指定偏移量的相对位置,SEEK_SET(从文件开头)、SEEK_CUR(从当前位置)、SEEK_END(从文件末尾)。
      • 返回值:成功返回新的文件偏移量(从文件开头计算的字节数),失败返回 - 1。
  6. 文件属性获取相关函数
    • stat()函数
      • 功能:获取文件的状态信息,如文件大小、权限、所有者等。
      • 参数
        • pathname:文件路径。
        • buf:指向struct stat结构体的指针,用于存储文件状态信息。
      • 返回值 :成功返回0,失败返回 - 1,并设置errnostruct stat结构体包含文件的多种属性,如st_size(文件大小)、st_mode(文件权限和类型)等。
    • fstat()函数
      • 功能 :和stat()类似,但它获取的是已打开文件(通过文件描述符)的状态信息。
      • 参数
        • fd:文件描述符。
        • buf:指向struct stat结构体的指针。
      • 返回值:成功返回0,失败返回 - 1。
  7. 文件关闭相关函数
    • close()函数
      • 功能:关闭一个打开的文件,释放文件描述符等资源。
      • 参数
        • fd:要关闭的文件的文件描述符。
      • 返回值:成功返回0,失败返回 - 1。关闭文件非常重要,不关闭可能导致资源泄漏、数据丢失等问题。
  8. 目录文件操作相关函数(用于访问目录中的文件)
    • opendir()函数
      • 功能 :打开一个目录,返回一个指向DIR结构体的指针,用于后续对目录的操作。
      • 参数
        • pathname:目录路径。
      • 返回值 :成功返回DIR结构体指针,失败返回NULL
    • readdir()函数
      • 功能 :读取打开目录中的一个条目(文件或子目录),返回一个指向struct dirent结构体的指针,包含条目的名称等信息。
      • 参数
        • dirpopendir()返回的DIR结构体指针。
      • 返回值 :成功返回struct dirent结构体指针,若已读完目录或出错则返回NULL
    • closedir()函数
      • 功能 :关闭之前由opendir()打开的目录,释放相关资源。
      • 参数
        • dirpDIR结构体指针。
      • 返回值:成功返回0,失败返回 - 1。

以下是上述各Linux文件访问相关函数的代码案例,展示了它们在实际编程中的具体用法:

1. open()函数示例

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    int fd;
    // 尝试以只读方式打开一个已存在的文件
    fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
        perror("打开文件失败");
        return 1;
    }
    printf("成功打开文件,文件描述符为: %d\n", fd);
    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    return 0;
}

在这个示例中,首先尝试以只读方式打开名为test.txt的文件,如果打开成功,会打印出获得的文件描述符,最后关闭该文件。

2. creat()函数示例

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    int fd;
    // 使用creat创建一个新文件,权限设置为0644(所有者读写,组和其他用户只读)
    fd = creat("new_file.txt", 0644);
    if (fd == -1) {
        perror("创建文件失败");
        return 1;
    }
    printf("成功创建文件,文件描述符为: %d\n", fd);
    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    return 0;
}

此代码尝试创建一个名为new_file.txt的新文件,指定了文件权限为0644,创建成功后打印文件描述符并关闭文件。

3. read()函数示例(结合open()函数使用)

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define BUFFER_SIZE 1024

int main() {
    int fd;
    ssize_t num_read;
    char buffer[BUFFER_SIZE];
    // 以只读方式打开文件
    fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
        perror("打开文件失败");
        return 1;
    }
    // 从文件中读取数据到缓冲区
    num_read = read(fd, buffer, sizeof(buffer));
    if (num_read == -1) {
        perror("读取文件失败");
        close(fd);
        return 1;
    } else if (num_read == 0) {
        printf("文件已读完(到达文件末尾)\n");
    } else {
        buffer[num_read] = '\0';  // 添加字符串结束符
        printf("读取到的内容: %s\n", buffer);
    }
    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    return 0;
}

这段代码先打开一个文件,然后使用read函数从文件中读取数据到定义的缓冲区,根据read函数的返回值判断读取情况,并做相应处理,最后关闭文件。

4. pread()函数示例(结合open()函数使用)

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define BUFFER_SIZE 1024

int main() {
    int fd;
    ssize_t num_read;
    char buffer[BUFFER_SIZE];
    off_t offset = 10;  // 从文件偏移量为10的位置开始读取

    // 以只读方式打开文件
    fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
        perror("打开文件失败");
        return 1;
    }
    // 使用pread从指定偏移量处读取数据
    num_read = pread(fd, buffer, sizeof(buffer), offset);
    if (num_read == -1) {
        perror("读取文件失败");
        close(fd);
        return 1;
    } else if (num_read == 0) {
        printf("已读到文件末尾\n");
    } else {
        buffer[num_read] = '\0';
        printf("从偏移量 %ld 处读取到的内容: %s\n", offset, buffer);
    }
    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    return 0;
}

该示例先打开文件,然后利用pread函数从指定的文件偏移量位置开始读取数据,读取后根据返回值处理数据并关闭文件。

5. write()函数示例(结合open()函数使用)

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define DATA "这是要写入文件的数据"

int main() {
    int fd;
    ssize_t num_written;
    // 以只写方式打开文件,如果文件不存在则创建
    fd = open("output.txt", O_WRONLY | O_CREAT, 0644);
    if (fd == -1) {
        perror("打开文件失败");
        return 1;
    }
    // 将数据写入文件
    num_written = write(fd, DATA, strlen(DATA));
    if (num_written == -1) {
        perror("写入文件失败");
        close(fd);
        return 1;
    }
    printf("成功写入 %zd 个字节到文件\n", num_written);
    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    return 0;
}

这里先打开(或创建)一个文件,再使用write函数将特定的数据写入文件,根据返回值判断写入情况,最后关闭文件。

6. pwrite()函数示例(结合open()函数使用)

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define DATA "新的数据"
#define OFFSET 20  // 在文件偏移量为20的位置写入数据

int main() {
    int fd;
    ssize_t num_written;
    // 以读写方式打开文件
    fd = open("test_write.txt", O_RDWR);
    if (fd == -1) {
        perror("打开文件失败");
        return 1;
    }
    // 使用pwrite在指定偏移量处写入数据
    num_written = pwrite(fd, DATA, strlen(DATA), OFFSET);
    if (num_written == -1) {
        perror("写入文件失败");
        close(fd);
        return 1;
    }
    printf("成功在偏移量 %d 处写入 %zd 个字节到文件\n", OFFSET, num_written);
    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    return 0;
}

代码先打开一个文件用于读写,接着通过pwrite函数在指定的文件偏移量位置写入数据,处理写入结果后关闭文件。

7. lseek()函数示例(结合open()函数使用)

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    int fd;
    off_t new_offset;
    // 以读写方式打开文件
    fd = open("test_lseek.txt", O_RDWR);
    if (fd == -1) {
        perror("打开文件失败");
        return 1;
    }
    // 将文件读写指针移动到文件末尾
    new_offset = lseek(fd, 0, SEEK_END);
    if (new_offset == -1) {
        perror("移动文件指针失败");
        close(fd);
        return 1;
    }
    printf("文件指针已移动到文件末尾,当前偏移量为: %ld\n", new_offset);
    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    return 0;
}

此示例打开一个文件后,使用lseek函数将文件读写指针移动到文件末尾,获取并打印新的偏移量,最后关闭文件。

8. stat()函数示例

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    struct stat file_stat;
    // 获取文件状态信息
    if (stat("test.txt", &file_stat) == -1) {
        perror("获取文件状态信息失败");
        return 1;
    }
    // 打印文件大小(字节数)
    printf("文件大小为: %ld 字节\n", file_stat.st_size);
    // 打印文件权限(八进制表示)
    printf("文件权限(八进制): %o\n", file_stat.st_mode & 0777);
    return 0;
}

该代码通过stat函数获取指定文件的状态信息,然后从struct stat结构体中提取文件大小和权限等信息并进行打印。

9. fstat()函数示例(结合open()函数使用)

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    int fd;
    struct stat file_stat;
    // 以只读方式打开文件
    fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
        perror("打开文件失败");
        return 1;
    }
    // 获取已打开文件的状态信息
    if (fstat(fd, &file_stat) == -1) {
        perror("获取文件状态信息失败");
        close(fd);
        return 1;
    }
    // 打印文件大小(字节数)
    printf("文件大小为: %ld 字节\n", file_stat.st_size);
    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    return 0;
}

代码先打开一个文件,然后使用fstat函数获取该已打开文件的状态信息,从中获取文件大小并打印,最后关闭文件。

10. close()函数示例(在上述各示例中都有体现,以下单独简单示意)

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    int fd = 3;  // 假设这里有一个文件描述符为3的已打开文件(实际应用中通常由open等函数获取)
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return 1;
    }
    printf("文件已成功关闭\n");
    return 0;
}

这个简单示例演示了使用close函数关闭一个给定文件描述符对应的文件,根据返回值判断关闭是否成功。

11. 目录文件操作相关函数示例

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main() {
    DIR *dp;
    struct dirent *ep;
    // 打开当前目录
    dp = opendir(".");
    if (dp == NULL) {
        perror("打开目录失败");
        return 1;
    }
    // 读取目录中的条目并打印文件名
    while ((ep = readdir(dp))!= NULL) {
        printf("文件名: %s\n", ep->d_name);
    }
    // 关闭目录
    if (closedir(dp) == -1) {
        perror("关闭目录失败");
        return 1;
    }
    return 0;
}

这段代码首先使用opendir函数打开当前目录,然后通过readdir函数循环读取目录中的文件和子目录条目,并打印它们的名称,最后使用closedir函数关闭打开的目录。

实践案例

  1. 简单的文件复制程序
    • 案例描述
      • 编写一个C程序,实现将一个文件的内容复制到另一个文件中。这个案例涉及到文件的打开、读取和写入操作。
    • 代码实现
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {
    int source_fd, destination_fd;
    ssize_t num_read, num_written;
    char buffer[BUFFER_SIZE];
    // 检查命令行参数是否正确
    if (argc!= 3) {
       fprintf(stderr, "用法: %s <源文件> <目标文件>\n", argv[0]);
       return 1;
    }
    // 打开源文件,以只读方式
    source_fd = open(argv[1], O_RDONLY);
    if (source_fd == -1) {
       perror("打开源文件失败");
       return 1;
    }
    // 打开目标文件,以写入方式,如果不存在则创建,权限为0644
    destination_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (destination_fd == -1) {
       perror("打开目标文件失败");
       close(source_fd);
       return 1;
    }
    // 从源文件读取数据并写入目标文件
    while ((num_read = read(source_fd, buffer, sizeof(buffer))) > 0) {
       num_written = write(destination_fd, buffer, num_read);
       if (num_written == -1) {
          perror("写入目标文件失败");
          close(source_fd);
          close(destination_fd);
          return 1;
       }
    }
    if (num_read == -1) {
       perror("读取源文件失败");
       close(source_fd);
       close(destination_fd);
       return 1;
    }
    // 关闭文件
    if (close(source_fd) == -1) {
       perror("关闭源文件失败");
       close(destination_fd);
       return 1;
    }
    if (close(destination_fd) == -1) {
       perror("关闭目标文件失败");
       return 1;
    }
    return 0;
}
  • 案例分析
    • 首先,程序通过open函数分别打开源文件和目标文件,注意打开方式的选择。然后,使用read函数从源文件读取数据到缓冲区,再通过write函数将缓冲区的数据写入目标文件。在循环过程中,不断重复读取和写入操作,直到read函数返回0,表示已经读取完源文件的内容。最后,关闭源文件和目标文件。
  1. 文件内容统计程序
    • 案例描述
      • 编写一个脚本(以Bash脚本为例),用于统计一个文本文件中单词的数量。这个案例涉及到文件的读取和简单的文本处理。
    • 代码实现
bash 复制代码
#!/bin/bash
if [ $# -ne 1 ]; then
    echo "用法: $0 <文件名>"
    exit 1
fi
filename="$1"
if [! -f "$filename" ]; then
    echo "文件不存在"
    exit 1
fi
word_count=$(cat "$filename" | wc -w)
echo "文件 $filename 中的单词数量为: $word_count"
  • 案例分析
    • 脚本首先检查命令行参数的个数是否正确,然后判断指定的文件是否存在。如果文件存在,使用cat命令读取文件内容,并通过管道|将内容传递给wc -w命令,wc -w用于统计单词数量。最后将统计结果输出。
  1. 文件权限修改程序
    • 案例描述
      • 编写一个C程序,用于修改指定文件的权限。这个案例涉及到文件属性的操作。
    • 代码实现
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
    if (argc!= 3) {
       fprintf(stderr, "用法: %s <文件名> <权限模式(八进制)>\n", argv[0]);
       return 1;
    }
    const char *filename = argv[1];
    mode_t mode = (mode_t) strtol(argv[2], NULL, 8);
    if (chmod(filename, mode) == -1) {
       perror("修改权限失败");
       return 1;
    }
    return 0;
}
  • 案例分析
    • 程序首先检查命令行参数的个数是否正确,然后将第二个参数(以八进制表示的权限模式)转换为mode_t类型。接着使用chmod函数来修改指定文件的权限。如果chmod函数返回 - 1,表示修改权限失败,程序会输出错误信息。
  1. 文件搜索程序
    • 案例描述
      • 编写一个Python程序,在指定目录及其子目录下搜索指定文件名的文件。这个案例涉及到目录的遍历和文件的检查。
    • 代码实现
python 复制代码
import os


def search_file(directory, filename):
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file == filename:
                print(os.path.join(root, file))


if __name__ == "__main__":
    directory = input("请输入要搜索的目录: ")
    filename = input("请输入要搜索的文件名: ")
    search_file(directory, filename)
  • 案例分析
    • 程序定义了一个search_file函数,使用os.walk函数来遍历指定目录及其子目录。os.walk返回一个三元组(root, dirs, files),其中root是当前遍历的目录路径,dirs是当前目录下的子目录列表,files是当前目录下的文件列表。在循环中,检查每个文件的名称是否与目标文件名相同,如果相同,则输出文件的完整路径。

用open()函数实现一个简单的文本编辑器

以下是一个使用C语言中的open()函数以及其他相关文件操作函数实现的简单文本编辑器示例,它可以实现创建新文件、打开已有文件、写入内容、读取内容以及保存修改等基本功能(这里只是一个简单的演示,没有复杂的文本编辑界面和功能,主要聚焦在文件操作层面)。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

#define MAX_BUFFER_SIZE 1024

// 函数声明
void create_file(const char *filename);
void open_file(int *fd, const char *filename);
void write_to_file(int fd, const char *content);
void read_file(int fd);
void save_file(int fd, const char *filename);
void close_file(int fd);

int main() {
    int choice, fd = -1;
    char filename[100];
    char content[MAX_BUFFER_SIZE];

    while (1) {
        printf("\n简单文本编辑器功能菜单:\n");
        printf("1. 创建新文件\n");
        printf("2. 打开现有文件\n");
        printf("3. 写入内容到文件\n");
        printf("4. 读取文件内容\n");
        printf("5. 保存文件\n");
        printf("6. 关闭文件并退出\n");
        printf("请输入你的选择: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                printf("请输入要创建的文件名: ");
                scanf("%s", filename);
                create_file(filename);
                break;
            case 2:
                printf("请输入要打开的文件名: ");
                scanf("%s", filename);
                open_file(&fd, filename);
                break;
            case 3:
                if (fd == -1) {
                    printf("请先打开或创建一个文件。\n");
                    continue;
                }
                printf("请输入要写入文件的内容(一行内容,按回车键结束): ");
                scanf("%s", content);
                write_to_file(fd, content);
                break;
            case 4:
                if (fd == -1) {
                    printf("请先打开一个文件。\n");
                    continue;
                }
                read_file(fd);
                break;
            case 5:
                if (fd == -1) {
                    printf("请先打开或创建一个文件。\n");
                    continue;
                }
                save_file(fd, filename);
                break;
            case 6:
                if (fd!= -1) {
                    close_file(fd);
                }
                return 0;
            default:
                printf("无效的选择,请重新输入。\n");
        }
    }

    return 0;
}

// 创建新文件的函数
void create_file(const char *filename) {
    int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        perror("创建文件失败");
        return;
    }
    close(fd);
    printf("文件 %s 创建成功。\n", filename);
}

// 打开文件的函数
void open_file(int *fd, const char *filename) {
    *fd = open(filename, O_RDWR);
    if (*fd == -1) {
        perror("打开文件失败");
        return;
    }
    printf("文件 %s 打开成功。\n", filename);
}

// 写入内容到文件的函数
void write_to_file(int fd, const char *content) {
    ssize_t num_written = write(fd, content, strlen(content));
    if (num_written == -1) {
        perror("写入文件失败");
        return;
    }
    printf("成功写入 %zd 个字节到文件。\n", num_written);
}

// 读取文件内容的函数
void read_file(int fd) {
    char buffer[MAX_BUFFER_SIZE];
    ssize_t num_read = read(fd, buffer, sizeof(buffer));
    if (num_read == -1) {
        perror("读取文件失败");
        return;
    } else if (num_read == 0) {
        printf("文件为空或已读到文件末尾。\n");
    } else {
        buffer[num_read] = '\0';
        printf("文件内容如下:\n%s\n", buffer);
    }
}

// 保存文件的函数(这里简单的重新写入覆盖原文件内容,可优化为更复杂的保存逻辑)
void save_file(int fd, const char *filename) {
    // 先关闭文件
    close(fd);
    // 再以只写方式打开,覆盖原内容写入
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        perror("保存文件失败");
        return;
    }
    char buffer[MAX_BUFFER_SIZE];
    lseek(fd, 0, SEEK_SET);
    ssize_t num_read = read(fd, buffer, sizeof(buffer));
    if (num_read!= -1 && num_read > 0) {
        buffer[num_read] = '\0';
        ssize_t num_written = write(fd, buffer, strlen(buffer));
        if (num_written == -1) {
            perror("保存文件时写入内容失败");
            close(fd);
            return;
        }
    }
    close(fd);
    printf("文件保存成功。\n");
}

// 关闭文件的函数
void close_file(int fd) {
    if (close(fd) == -1) {
        perror("关闭文件失败");
        return;
    }
    printf("文件已关闭。\n");
}

以下是对这个代码的详细说明:

1. 整体结构和主函数逻辑

  • 程序通过一个无限循环展示功能菜单,让用户选择相应的操作,包括创建文件、打开文件、写入内容、读取内容、保存文件以及关闭文件并退出等选项。
  • 根据用户输入的不同选择,调用相应的函数来执行具体的文件操作。在进行某些操作(如写入、读取、保存等)前,会先判断文件是否已经正确打开(通过文件描述符是否为 - 1 来判断),若未打开则提示用户先打开或创建文件。

2. 各个功能函数介绍

  • create_file函数
    • 使用open()函数以O_WRONLY | O_CREAT | O_TRUNC模式打开指定文件名的文件,这意味着如果文件不存在则创建它,若存在则截断(清空)其原有内容,权限设置为0644(所有者读写,所属组和其他用户只读)。
    • 如果open操作成功,获取到文件描述符后,使用close函数关闭文件,因为这里只是创建操作,暂时不需要对文件进行读写,关闭后提示用户文件创建成功;若open失败,则通过perror函数打印错误信息。
  • open_file函数
    • 接收一个指向整数(用于存储文件描述符)的指针和文件名作为参数,使用open()函数以O_RDWR(读写)模式打开文件。
    • 若打开成功,将获取到的文件描述符赋值给传入的指针指向的变量,并提示用户文件打开成功;若打开失败,则通过perror函数打印错误信息。
  • write_to_file函数
    • 接收文件描述符和要写入的内容字符串作为参数,使用write()函数将内容写入文件。
    • 根据write函数的返回值判断写入是否成功,若成功则打印写入的字节数,若失败则通过perror函数打印错误信息。
  • read_file函数
    • 接收文件描述符作为参数,定义一个缓冲区数组,使用read()函数从文件中读取内容到缓冲区。
    • 根据read函数的返回值进行不同处理:返回 - 1 表示读取失败,打印错误信息;返回 0 表示文件为空或已读到文件末尾,给出相应提示;若读取到有效内容,则在缓冲区末尾添加字符串结束符后打印出文件内容。
  • save_file函数
    • 先关闭已打开的文件(因为要重新以写入模式打开覆盖原内容),然后再以O_WRONLY | O_CREAT | O_TRUNC模式打开文件,这样可以确保将当前内存中的内容重新覆盖写入文件(这里只是简单实现了重新写入覆盖,可根据实际需求优化保存逻辑,比如实现追加保存等更复杂的功能)。
    • 通过lseek函数将文件指针移动到文件开头,读取文件现有内容到缓冲区,再将缓冲区内容写回文件(这里同样可以优化,比如考虑部分写入等情况),若写入成功则关闭文件并提示文件保存成功,若出现错误则打印错误信息并关闭文件。
  • close_file函数
    • 接收文件描述符作为参数,使用close()函数关闭文件,根据返回值判断关闭是否成功,若失败则通过perror函数打印错误信息,若成功则提示文件已关闭。

请注意,这个简单文本编辑器只是一个基础的示例,实际应用中的文本编辑器功能要复杂得多,例如支持多行编辑、文本格式处理、光标定位等功能,还需要更好的用户交互界面(如图形界面或者更友好的命令行交互方式等),但这个示例可以帮助理解在Linux环境下如何通过open()等文件操作函数来进行基本的文件读写与管理。

相关推荐
__NULL__USER1 小时前
petalinux-adi ---添加AD9361驱动(二)
linux·驱动开发
vvw&2 小时前
如何在 Linux 服务器上部署 Pydio Cells 教程
linux·运维·服务器·自动化·debian·github·私有化部署
枫叶红花2 小时前
【Linux系统编程】:信号(1)——前置知识,了解信号
linux·运维·服务器
明月清了个风3 小时前
数据结构与算法学习笔记----Floyd算法
笔记·学习·算法
芳菲菲其弥章3 小时前
数据结构经典算法总复习(上卷)
数据结构·算法
致Great3 小时前
不是炒作GenAI!终于有 BERT 的替代品了
算法
7yewh3 小时前
嵌入式驱动RK3566 HDMI eDP MIPI 背光 屏幕选型与调试提升篇-eDP屏
linux·arm开发·驱动开发·嵌入式硬件·嵌入式linux·rk·edp
Teacher_Wyh3 小时前
算法知识-18-STL
开发语言·c++·算法
南宫生4 小时前
力扣-图论-15【算法学习day.65】
java·学习·算法·leetcode·图论
mit6.8244 小时前
[数据结构#2] 图(1) | 概念 | 邻接矩阵 | 邻接表 | 模拟
算法·深度优先·图论