摘要:Linux系统管理与开发课程中对于文件的读写操作的认识并且运用C语言进行模拟读、写和复制操作。
文件开关以及读写说明
读操作read()
read(int fd, void *buf, size_t count);
len: 请求读取的字节数
返回值:
-1 :读取失败
0:没有读取到数据
n:读取到的字节数(n:1~len)
实际情况下:
< 0 : 失败
= len: 正常读取
= 0~len-1: 读取完毕
写操作write()
write(int fd, const void *buf, size_t count);
返回值:
-1 :读取失败
n:写入字符个数(n:1~len)
打开文件open()/creat()
creat(文件名称,权限模式); = open(文件名称,O_CREAT,权限模式);
类型:
O_RDONLY | O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC |
---|---|---|---|---|---|
只读 | 只写 | 读写 | 末尾追加 | 若文件存在,此标志无用;若不存在,建新文件 | 若文件存在,则长度被截为0,属性不变 |
权限模式:
S_I <权限><对象>
权限:R, W, X, RWX
对象:USR, GRP, OTH, U, G, O
举个栗子:
usr:rwx; group:rw; other:r;
creat("test", S_IRWXU | S_IRGRP |S_IROTH);
=
open("test",O_CREAT, S_IRWXU | S_IRGRP |S_IROTH)
tips:
权限位:3个八进制数
764
creat("test",010764);
关闭文件close()
close(句柄);
读操作
解释一下int main(int argc, char** argv)
的意思:
例如一条指令:cp abc.txt xyz.log
则 argc = 3
(指令的三个部分) argv[0] = cp
argv[1]=abc.txt
argv[2]= xyz.log
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define LEN 512
int bail(const char* str){
printf("Error(%d):",errno);
perror(str);
exit(-1);
}
int main(int argc, char** argv){
int fd = -1;
char buf[LEN] = {0};
int read_return = -1;
fd = open(argv[1],O_RDONLY);
if(fd < 0)
bail("open file error.");
printf("fd = %d \n",fd);
read_return = read(fd, buf, sizeof(buf));
while(read_return > 0)
{
printf("%s",buf);
memset(buf, 0, sizeof(buf));
read_return = read(fd, buf, sizeof(buf));
}
if (read_return < 0){
close(fd);
bail("read file error.");
}
close(fd);
return 0;
}
写操作
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define LEN 512
int bail(const char* str)
{
printf("Error(%d):",errno);
perror(str);
exit(-1);
}
int main(int argc, char** argv)
{
int fd = -1;
char buf[LEN] = {0};
int write_return = -1;
int read_return = -1;
//fd = open(argv[1],O_WRONLY); //以只写的方式写入
//fd = open(argv[1],O_WRONLY | O_APPEND); //以只写+尾部追加的方式写入
fd = open(argv[1],O_CREAT | O_WRONLY | O_APPEND, S_IRUSR | S_IRGRP | S_IROTH);
if(fd < 0)
bail("open file error.");
printf("fd = %d \n",fd);
printf(">");
gets(buf);
while(strcmp(buf, "quit") != 0)
{
write_return = write(fd, buf, strlen(buf));
if(write_return <0)
{
close(fd);
bail("Write file error.");
}
memset(buf , 0, sizeof(buf));
printf(">");
gets(buf);
}
close(fd);
return 0;
}
复制功能的实现
- 打开源文件
- 创建目标文件
- 读取源文件
- 写入目标文件
- 关闭句柄退出
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define LEN 512
int bail(const char* str)
{
printf("Error(%d):",errno);
perror(str);
exit(-1);
}
int main(int argc, char** argv)
{
int read_fd = -1;
int write_fd = -1;
char buf[LEN] = {0};
int write_return = -1;
int read_return = -1;
read_fd = open(argv[1],O_RDONLY);
write_fd = open(argv[2],O_CREAT | O_RDWR , 010755);
if(read_fd < 0)
bail("open file error.");
if(write_fd < 0)
{
close(read_fd);
bail("Create file error.");
}
read_return = read(read_fd, buf, sizeof(buf));
while( read_return > 0)
{
write_return = write(write_fd, buf , read_return);
if(write_return < read_return)
{
close(read_fd);
close(write_fd);
bail("Write file error.");
}
memset(buf, 0, sizeof(buf));
read_return = read(read_fd, buf, sizeof(buf));
}
if(read_fd < 0)
{
close(read_fd);
close(write_fd);
bail("Read file error.");
}
close(read_fd);
close(write_fd);
return 0;
}
tips:
复制操作中关于文件权限判断和使用的问题未能成功实现,留待下次更新。
---3.18更新---
访问文件(判断权限)
access函数使用方法:
access("文件名称",测试权限)
测试权限:
R_OK:读可以
W_OK:写可以
X_OK:执行可以
F_OK:文件存在
返回值:
0:测试成功
-1:测试失败
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
int bail(const char* str){
printf("Error(%d):",errno);
perror(str);
exit(-1);
}
int main(int argc, char** argv)
{
int ret = -1;
ret = access(argv[1],F_OK);
//ret = access(argv[1],F_OK | X_OK); //同时检测满足文件是否同时存在和可执行
if (ret < 0)
printf("File not exist.\n");
else
printf("File exist.\n");
close(ret);
return 0;
}
这就很好的解释了在读写前可以使用access函数判断权限。
读操作:
ret = access(argv[1],F_OK | R_OK);
if (ret ==0)
fd = open();
写操作:
ret = access(argv[1],F_OK );
if(ret <0)
fd = creat();
else
printf("overwrite?");
获取状态信息
stat函数:
struct stat st;
stat(“文件名”,&st);
返回值:
-1:失败
st返回值:
st.st_size:文件大小
st.st_mode:文件类型、权限
st.st_xtim:时间相关参数(秒为单位,用ctime转换)
st.mode:
①st.mode&S_IFMT
②宏函数:S_ISDIR、S_ISREG、S_ISLNK、S_ISFIFO、S_ISCHR、S_ISSOCK
获取文件信息
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
int bail(const char* str){
printf("Error(%d):",errno);
perror(str);
exit(-1);
}
int main(int argc, char** argv)
{
int ret = -1;
struct stat bs;
memset(&bs,0,sizeof(bs));
ret = stat(argv[1],&bs);
if (ret < 0)
bail("Stat error.\n");
if (S_ISDIR(bs.st_mode))
printf(" %s \t","D");
else if (S_ISREG(bs.st_mode))
printf(" %s \t","-");
else if (S_ISLNK(bs.st_mode))
printf(" %s \t","l");
else
printf(" %s \t","u");
printf("%lld\t",bs.st_size);
printf("%o\t",bs.st_mode);
printf("%s\t",ctime(&bs.st_atime));
return 0;
}
一下为运行截图
获取权限信息并复制到另一文件
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
int bail(const char* str){
printf("Error(%d):",errno);
perror(str);
exit(-1);
}
int main(int argc, char** argv)
{
int ret = -1;
int dfd = -1;
struct stat bs;
memset(&bs , 0, sizeof(bs));
ret = stat(argv[1],&bs);
dfd = creat(argv[2],bs.st_mode);
return 0;
}
如下图所示
Comments | 0 条评论