linux_1">linux文件访问相关函数
- 打开文件函数 -
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)。文件描述符用于后续对文件的读写等操作。例如,
0
、1
、2
分别是标准输入、标准输出和标准错误输出的文件描述符,而新打开的文件描述符通常是大于等于3
的整数。 - 失败时返回
-1
,并且会设置errno
来指示错误原因,常见的错误原因可能是文件不存在、权限不足等。可以通过perror
函数来打印错误信息。
- 成功时返回一个非负整数,这个整数是文件描述符(File Descriptor)。文件描述符用于后续对文件的读写等操作。例如,
- 示例代码:
- 函数原型:
#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;
}
- 读取文件函数 -
read
- 函数原型:
ssize_t read(int fd, void *buf, size_t count);
- 参数说明:
fd
:这是之前通过open
函数打开文件得到的文件描述符。buf
:这是一个指向缓冲区的指针,用于存储读取到的文件内容。缓冲区的大小应该足够容纳要读取的数据。例如,可以定义一个字符数组char buffer[1024];
来作为缓冲区。count
:这是要读取的字节数。例如,如果count
为10
,则最多读取10
个字节的文件内容。
- 返回值:
- 成功时返回实际读取到的字节数。如果返回值小于
count
,可能是已经到达文件末尾或者被信号中断等原因。例如,返回0
表示已经到达文件末尾。 - 失败时返回
-1
,并且会设置errno
来指示错误原因,常见的错误原因可能是文件描述符无效、权限不足等。
- 成功时返回实际读取到的字节数。如果返回值小于
- 示例代码(续接上面
open
函数的示例):
- 函数原型:
#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;
}
- 写入文件函数 -
write
- 函数原型:
ssize_t write(int fd, const void *buf, size_t count);
- 参数说明:
fd
:文件描述符,和read
函数中的fd
类似,是通过open
函数打开文件得到的。buf
:这是一个指向包含要写入数据的缓冲区的指针。例如,如果要写入一个字符串,可以定义char data[] = "Hello, World!";
,然后将data
作为buf
参数。count
:这是要写入的字节数。例如,对于上面的字符串data
,count
可以是strlen(data)
。
- 返回值:
- 成功时返回实际写入的字节数。如果返回值小于
count
,可能是磁盘空间不足、被信号中断等原因。 - 失败时返回
-1
,并且会设置errno
来指示错误原因,常见的错误原因可能是文件描述符无效、权限不足等。
- 成功时返回实际写入的字节数。如果返回值小于
- 示例代码(写入一个新文件):
- 函数原型:
#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;
}
- 关闭文件函数 -
close
- 函数原型:
int close(int fd);
- 参数说明:
fd
:这是要关闭的文件的文件描述符,是之前通过open
函数打开文件得到的。
- 返回值:
- 成功时返回
0
。 - 失败时返回
-1
,并且会设置errno
来指示错误原因,常见的错误原因可能是文件描述符无效等。
- 成功时返回
- 重要性:
- 关闭文件是一个重要的操作,它可以释放文件描述符资源,确保数据的完整性。如果不关闭文件,可能会导致文件损坏、资源泄漏等问题。例如,在写入文件后,如果没有正确关闭文件,数据可能没有完全写入磁盘,导致数据丢失。
- 函数原型:
- 文件打开与创建相关函数
- 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()
函数使用更广泛,因为它功能更灵活。
- 功能:创建一个新文件。它等效于
- open()函数
- 文件读取相关函数
- read()函数
- 功能:从打开的文件中读取数据。
- 参数:
fd
:文件描述符,由open()
等函数返回。buf
:指向存储读取数据的缓冲区的指针,例如char buffer[1024];
。count
:希望读取的字节数。
- 返回值:成功时返回实际读取的字节数。如果返回0,表示已读到文件末尾;返回 - 1表示出错,同时设置
errno
。
- pread()函数
- 功能:从指定文件偏移量处读取数据,读取操作不会改变文件偏移量。
- 参数:
fd
:文件描述符。buf
:缓冲区指针。count
:读取字节数。offset
:文件中的偏移量,从该位置开始读取。
- 返回值:和
read()
函数类似,成功返回实际读取字节数,0表示文件末尾, - 1表示出错。
- read()函数
- 文件写入相关函数
- write()函数
- 功能:将数据写入打开的文件。
- 参数:
fd
:文件描述符。buf
:指向包含要写入数据的缓冲区的指针。count
:要写入的字节数。
- 返回值:成功时返回实际写入的字节数,可能小于
count
(如磁盘空间不足);返回 - 1表示出错,同时设置errno
。
- pwrite()函数
- 功能:在指定文件偏移量处写入数据,写入操作不会改变文件偏移量。
- 参数:
fd
:文件描述符。buf
:包含要写入数据的缓冲区指针。count
:写入字节数。offset
:文件中的偏移量,在该位置写入。
- 返回值:和
write()
函数类似,成功返回实际写入字节数, - 1表示出错。
- write()函数
- 文件定位相关函数
- lseek()函数
- 功能:移动文件读写指针的位置,用于在文件中随机访问。
- 参数:
fd
:文件描述符。offset
:偏移量,正数表示向文件尾方向移动,负数表示向文件头方向移动。whence
:指定偏移量的相对位置,SEEK_SET
(从文件开头)、SEEK_CUR
(从当前位置)、SEEK_END
(从文件末尾)。
- 返回值:成功返回新的文件偏移量(从文件开头计算的字节数),失败返回 - 1。
- lseek()函数
- 文件属性获取相关函数
- stat()函数
- 功能:获取文件的状态信息,如文件大小、权限、所有者等。
- 参数:
pathname
:文件路径。buf
:指向struct stat
结构体的指针,用于存储文件状态信息。
- 返回值:成功返回0,失败返回 - 1,并设置
errno
。struct stat
结构体包含文件的多种属性,如st_size
(文件大小)、st_mode
(文件权限和类型)等。
- fstat()函数
- 功能:和
stat()
类似,但它获取的是已打开文件(通过文件描述符)的状态信息。 - 参数:
fd
:文件描述符。buf
:指向struct stat
结构体的指针。
- 返回值:成功返回0,失败返回 - 1。
- 功能:和
- stat()函数
- 文件关闭相关函数
- close()函数
- 功能:关闭一个打开的文件,释放文件描述符等资源。
- 参数:
fd
:要关闭的文件的文件描述符。
- 返回值:成功返回0,失败返回 - 1。关闭文件非常重要,不关闭可能导致资源泄漏、数据丢失等问题。
- close()函数
- 目录文件操作相关函数(用于访问目录中的文件)
- opendir()函数
- 功能:打开一个目录,返回一个指向
DIR
结构体的指针,用于后续对目录的操作。 - 参数:
pathname
:目录路径。
- 返回值:成功返回
DIR
结构体指针,失败返回NULL
。
- 功能:打开一个目录,返回一个指向
- readdir()函数
- 功能:读取打开目录中的一个条目(文件或子目录),返回一个指向
struct dirent
结构体的指针,包含条目的名称等信息。 - 参数:
dirp
:opendir()
返回的DIR
结构体指针。
- 返回值:成功返回
struct dirent
结构体指针,若已读完目录或出错则返回NULL
。
- 功能:读取打开目录中的一个条目(文件或子目录),返回一个指向
- closedir()函数
- 功能:关闭之前由
opendir()
打开的目录,释放相关资源。 - 参数:
dirp
:DIR
结构体指针。
- 返回值:成功返回0,失败返回 - 1。
- 功能:关闭之前由
- opendir()函数
以下是上述各Linux文件访问相关函数的代码案例,展示了它们在实际编程中的具体用法:
1. open()
函数示例
#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()
函数示例
#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()
函数使用)
#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()
函数使用)
#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()
函数使用)
#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()
函数使用)
#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()
函数使用)
#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()
函数示例
#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()
函数使用)
#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()
函数示例(在上述各示例中都有体现,以下单独简单示意)
#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. 目录文件操作相关函数示例
#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
函数关闭打开的目录。
实践案例
- 简单的文件复制程序
- 案例描述:
- 编写一个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,表示已经读取完源文件的内容。最后,关闭源文件和目标文件。
- 首先,程序通过
- 文件内容统计程序
- 案例描述:
- 编写一个脚本(以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
用于统计单词数量。最后将统计结果输出。
- 脚本首先检查命令行参数的个数是否正确,然后判断指定的文件是否存在。如果文件存在,使用
- 文件权限修改程序
- 案例描述:
- 编写一个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,表示修改权限失败,程序会输出错误信息。
- 程序首先检查命令行参数的个数是否正确,然后将第二个参数(以八进制表示的权限模式)转换为
- 文件搜索程序
- 案例描述:
- 编写一个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()
函数以及其他相关文件操作函数实现的简单文本编辑器示例,它可以实现创建新文件、打开已有文件、写入内容、读取内容以及保存修改等基本功能(这里只是一个简单的演示,没有复杂的文本编辑界面和功能,主要聚焦在文件操作层面)。
#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()
等文件操作函数来进行基本的文件读写与管理。