文件管理(一)
编写代码,完成以下功能:
1.创建文件file1,写入字符串“abcdefghijklmn”;
2.创建文件file2,写入字符串“ABCDEFGHIJKLMN”;
3.读取file1中的内容,写入file2,使file2中的字符串内容为“ABCDEFGHIJKLMNabcdefghijklmn ”
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main()
{
int fd1,fd2;
char str[14];
fd1 = open("file1",O_RDWR|O_CREAT,S_IRWXU);
if(fd1 < 0)
perror("open");
write(fd1,"abcdefghijklmn",14);
lseek(fd1,0,SEEK_SET);
fd2 = open("file2",O_RDWR|O_CREAT,S_IRWXU);
if(fd2 < 0)
perror("open");
lseek(fd2,0,SEEK_END);
write(fd2,"ABCDEFGHIJKLMN",14);
read(fd1,str,14);
lseek(fd2,14,SEEK_SET);
write(fd2,str,14);
close(fd1);
close(fd2);
system("cat file2");
printf("\n");
system("rm -f file1 file2");
return 0;
}
详细代码解释:
-
包含文件操作头文件fcntl、unistd、sys/stat等
-
使用open函数打开文件file1和file2,如果不存在则创建
-
将"abcdefghijklmn"写入文件file1
-
将文件指针移到开头SEEK_SET
-
将"ABCDEFGHIJKLMN"写入文件file2末尾
-
读取file1内容到缓冲区str
-
将文件指针移到file2开头SEEK_SET
-
将str内容写入file2
-
关闭文件描述符
-
使用system调用cat查看file2内容
-
使用system调用rm删除文件
主要功能:
-
使用open函数打开文件进行读写
-
使用write写入文件,read读取文件
-
使用lseek移动文件指针位置
-
将一个文件内容拷贝到另一个文件末尾
-
关闭文件并调用系统命令操作文件
其中函数解释为:
- open(): 打开文件,返回文件描述符。
- 参数1:文件名
- 参数2:打开模式
- 参数3:文件权限
- close(): 关闭文件描述符。
- 参数:文件描述符
- write(): 向文件写入数据。
- 参数1:文件描述符
- 参数2:数据缓冲区
- 参数3:写入字节数
- read(): 从文件读取数据。
- 参数1:文件描述符
- 参数2:数据缓冲区
- 参数3:最大读取字节数
- lseek(): 设置/移动文件读写指针位置。
- 参数1:文件描述符
- 参数2:偏移量
- 参数3:参考位置
- perror(): 打印错误信息。
- 参数:错误前缀字符串
- system(): 调用外部命令。
文件管理(二)
编写代码,完成以下功能:
1.创建新文件,该文件具有用户读写权限。
2.采用dup/dup2/fcntl复制一个新的文件描述符,通过新文件描述符向文件写入“class_name”字符串;
3.通过原有的文件描述符读取文件中的内容,并且打印显示;
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
int fd,fd1;
char *str = "yidongyiban";
fd = open("file",O_CREAT|O_RDWR);
if(fd < 0)
perror("open");
fd1 = dup(fd);
if(fd1 < 0)
perror("dup");
write(fd1,str,strlen(str));
lseek(fd,0,SEEK_SET);
char buf[12];
read(fd,buf,12);
printf("The buf is:%s\n",buf);
close(fd);
close(fd1);
system("rm -f file");
return 0;
}
详细代码解释:
- 首先包含了文件操作相关头文件
- 主函数打开文件fd,写入字符串
- 使用dup函数复制文件描述符fd,返回新的fd1
- 通过fd1写入文件,fd指针不变
- 使用lseek移动fd指针到开头
- 读取fd内容显示在屏幕上
- 关闭两个文件描述符
- 删除文件
主要功能:
-
dup函数可以复制一个文件描述符,获得新的描述符来操作同一个文件
-
通过dup复制后,可以通过不同的描述符并行读写同一个文件
-
这里dup后通过fd1写入,fd指针不变,再通过fd读取显示效果
-
演示dup函数用于一个文件同时读写的用法
-
其他函数如open、write、read等完成基本文件操作
函数解释:
- open(): 打开文件,返回文件描述符
- 参数1:文件名
- 参数2:打开模式
- 返回值:文件描述符
- dup(): 复制文件描述符
- 参数:需要复制的文件描述符
- 返回值:新的文件描述符
- write(): 向文件写入数据
- 参数1:文件描述符
- 参数2:数据缓冲区
- 参数3:写入字节数
- lseek(): 设置文件读写指针位置
- 参数1:文件描述符
- 参数2:偏移量
- 参数3:参考位置
- read(): 从文件读取数据
- 参数1:文件描述符
- 参数2:数据缓冲区
- 参数3:最大读取字节数
- close(): 关闭文件描述符
- 参数:文件描述符
- perror(): 打印错误信息
- 参数:错误前缀字符串
- system(): 调用外部命令
注意点:fd = open("file",O_CREAT|O_RDWR);
-
open函数用于打开文件,返回文件描述符fd
-
第一个参数"file"指定要打开的文件名
-
第二个参数O_CREAT|O_RDWR指定打开模式:
-
O_CREAT表示如果文件不存在则创建该文件
-
O_RDWR表示打开文件用于读写
-
-
O_CREAT和O_RDWR使用位或运算符"|"组合
-
这样可以实现两种功能:
- 如果文件存在就打开用于读写
- 如果文件不存在就创建文件并打开用于读写
-
成功打开后会返回非负的文件描述符fd
-
文件描述符可以用于后续的读写操作
文件管理(三)
编写程序实现以下功能:
1.输入文件名称,能够判断文件类型,判断实际用户对该文件具有哪些存取权限;
2.要求打印出文件类型信息,inode节点编号,链接数目,用户id,组id,文件大小信息;
3.修改文件的权限为当前用户读写,组内用户读写,组外用户无权限。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc,char *argv[])
{
if(argc < 2)
{
printf("Please input the filename!\n");
return 0;
}
struct stat statbuf;
int i;
for(i = 1;i < argc;i++)
{
if(lstat(argv[i],&statbuf) < 0)
perror("lstat");
char *buf;
if(S_ISREG(statbuf.st_mode))
buf = "Regular file!";
else if(S_ISDIR(statbuf.st_mode))
buf = "Directory file!";
else if(S_ISCHR(statbuf.st_mode))
buf = "Char file!";
else
buf = "Other file!";
printf("The %s is:%s\n",argv[i],buf);
printf("The %s mode is:%d\n",argv[i],statbuf.st_mode);
printf("The %s inode is:%d\n",argv[i],statbuf.st_ino);
printf("The %s uid is:%d\n",argv[i],statbuf.st_uid);
printf("The %s gid is:%d\n",argv[i],statbuf.st_gid);
printf("The %s size is:%d\n",argv[i],statbuf.st_size);
printf("The %s link num is:%d\n",argv[i],statbuf.st_nlink);
}
for(i = 1;i < argc;i++)
{
if(access(argv[i],R_OK))
printf("The user can read the %s\n",argv[i]);
else if(access(argv[i],W_OK))
printf("The user can write the %s\n",argv[i]);
else if(access(argv[i],X_OK))
printf("The user can read and write the %s\n",argv[i]);
}
for(i = 1;i < argc;i++)
{
if(chmod(argv[i],0660) < 0)
perror("chmod");
else
printf("The file.mode chmod successful!\n");
}
return 0;
}
详细代码解释:
- 使用stat结构体获取文件类型、权限、大小等信息
- 通过S_ISxxx宏判断文件类型
- 使用access检查用户对文件各种操作权限
- 使用chmod修改文件权限
主要功能:
-
lstat获取文件状态信息填充到stat结构体
-
打印文件类型、i节点、用户组等信息
-
access检查文件读写执行权限
-
chmod修改文件权限模式为0660(rwxrwxr-x)(首0为八进制标志)
-
命令行参数传递文件名进行操作
函数具体解释:
-
lstat():获取文件状态信息。参数为文件名和stat结构体指针。
-
S_ISREG/DIR/CHR:判断文件类型的宏,根据mode返回true或false。
-
access():检查文件权限。参数为文件名和权限常量RWX。
-
chmod():修改文件权限。参数为文件名和新权限模式。
-
stat:文件状态结构体。包含文件类型、大小、权限等信息。
-
perror():打印错误信息。参数为错误前缀。
-
printf():格式化输出。
其中需要注意:
- lstat获取文件状态信息到stat结构体
- 判断文件类型
- access检查文件权限
- chmod修改文件权限
- 通过stat结构体打印文件详细信息
参数问题:
- lstat()
- 参数1:文件名字符串
- 参数2:stat结构体指针,用于存储获取的文件属性信息
- access()
- 参数1:文件名字符串
- 参数2:访问权限模式常量,如R_OK
- chmod()
- 参数1:文件名字符串
- 参数2:新文件权限模式值
- stat结构体
- 用于存储文件各种属性信息,如大小、类型、权限等
- perror()
- 参数1:错误前缀字符串
- printf()
- 参数1:格式字符串
- 后续参数:要打印的变量值
- main()
- 参数1:参数个数
- 参数2:参数列表字符串数组
补充文件类型的常规文件位:
文件类型位(File Type Bits)存储在struct stat结构体的st_mode字段中。
在Linux系统下,文件类型位使用S_IFMT宏定义的文件类型掩码来提取:
#define S_IFMT 0170000
文件类型位包括:
-
S_IFREG: 常规文件(Regular File),该文件包含数据或代码。0x8000
-
S_IFDIR: 目录(Directory),0x4000
-
S_IFCHR: 字符设备文件(Character Device File),0x2000
-
S_IFBLK: 块设备文件(Block Device File),0x6000
-
S_IFIFO: 管道(FIFO/Named Pipe),0x1000
-
S_IFLNK: 符号链接(Symbolic Link), 0xa000
-
S_IFSOCK: 套接字(Socket), 0xc000
其中,S_IFREG的值0x8000就代表文件类型位中的常规文件标识。
通过与该值进行比对,可以使用S_ISREG宏判断一个文件是否是常规文件类型。
所以在Linux系统中,文件类型位中标识常规文件的具体值就是0x8000,对应S_IFREG这个文件类型常量。