只读:查看系统内部比较重要的文件有必要使用只读的方式打开
只写
可读可写
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
int main(void)
{
int fd = -1;//文件描述符
char buf[100] = {0};
char writebuf[20] = "i love linux LT.";
int ret = 0;
extern int errno;
/*打开一个文件*/
fd = open("a.txt",O_RDONLY);//以只读权限打开,所以后面的写入操作会发生错误
if(-1 == fd)
{
printf("文件打开错误.\n");
}
else
{
printf("文件打开成功. fd = %d.\n",fd);
}
/*写文件*/
ret = write(fd, writebuf, strlen(writebuf));
if(ret < 0)
{
printf("写入失败.\n");
printf("errno:%d\n", errno); //显示错误号
printf("ERR :%s\n", strerror(errno)); //显示错误信息
}
else
{
printf("写入的字节数为:%d.\n",ret);
}
/*读取文件的内容*/
/*
ret = read(fd, buf, 20);
if(-1 == ret)
{
printf("读取失败.\n");
}
else
{
printf("读出的字节数为:%d.",ret);
printf("文件内容为:[%s].",buf);
}
*/
/*关闭一个文件*///关闭一般都不会出什么错误,所以返回值也不去管它了
close(fd);
return 0;
}
root@ubuntu:/mnt/hgfs/05_winshare# cp a.c b.c //拷贝文件
root@ubuntu:/mnt/hgfs/05_winshare# ls
root@ubuntu:/mnt/hgfs/05_winshare# gcc b.c -o b.out //按照自己的需求生成
root@ubuntu:/mnt/hgfs/05_winshare# ls
a.c a.out arm-2009q3.tar.bz2 a.txt b.c b.out s5pv210
root@ubuntu:/mnt/hgfs/05_winshare# ./b.out
文件打开成功. fd = 3.
写入失败.
errno:9
ERR :Bad file descriptor
其余的只要记住这两个就可以了
注意,在中间出错的地方就要返回return -1 防止程序连续出错。
可以用return -1,只能在man函数中用,
比较正式的结束函数,应该是终止一个进程,应该使用exit 或者_exit 或者 _Exit ,_exit(0)
第一个是库函数 后两个是系统调用API函数
1、Standard commands (标准命令)
2、System calls (系统调用)
3、Library functions (库函数)
man exit之后
说明 exit是库函数,因为上面标着3 库函数
man _exit 之后
说明是系统调用API函数
vi a.txt 其中a.txt可以是一个完全不存在的文件,vi打开即建立,vi就是调用系统的open的O_creat API
open一个不存在的文件
如果O_CREAT 一个已经存在的文件,
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
int main(void)
{
int fd = -1;//文件描述符
char buf[100] = {0};
char writebuf[20] = "i love linux LT.";
int ret = 0;
extern int errno;
/*打开一个文件*/
fd = open("a.txt",O_WRONLY | O_CREAT); //加入o_creat的控制位
if(-1 == fd)
{
printf("文件打开错误.\n");
}
else
{
printf("文件打开成功. fd = %d.\n",fd);
}
/*写文件*/
ret = write(fd, writebuf, strlen(writebuf));
if(ret < 0)
{
printf("写入失败.\n");
printf("errno:%d\n", errno); //显示错误号
printf("ERR :%s\n", strerror(errno)); //显示错误信息
}
else
{
printf("写入的字节数为:%d.\n",ret);
}
/*读取文件的内容*/
/*
ret = read(fd, buf, 20);
if(-1 == ret)
{
printf("读取失败.\n");
}
else
{
printf("读出的字节数为:%d.",ret);
printf("文件内容为:[%s].",buf);
}
*/
/*关闭一个文件*///关闭一般都不会出什么错误,所以返回值也不去管它了
close(fd);
return 0;
}
当我们使用oreat,但是文件已经存在,这种情况还是会打开成功,可以试试嘛,就是把原来的覆盖掉了,
如果我们本来想创建一个新文件,结果新文件名就是一个老文件名,这样老文件就搞丢失了,我们想要的是如果creat的新文件名字已经存在,编译器可以报错,此时O_EXCL登场,
我在o_creat时候,想给新建的文件不同的权限,怎么在新建的时候操作。可以使用第三个参数指定文件的权限。
在vi文件内查找mode字符串 输入 /mode 即可
创建一个不可执行的用,0666,这个现用现查就可以了
现在要知道mode位是指定权限的,如果不是创建文件,mode位就是没用的
阻塞和非阻塞
死等着排队的:阻塞式的,有可能被卡住,因为条件不具备,要等待条件成熟,函数被阻塞就不能立马返回
先干别的事情,一会再来:非阻塞式的,调用非阻塞的函数一定会立即返回,但是不一定一定完成任务了
一个结果有保障,时间没保障
一个时间有保障,结构没保障
看应用了
阻塞和非阻塞的概念只用于设备文件,而不用于普通文件
设备文件:就是linux下的设备 UART或者其他的
有很多系统调用API 阻塞或者非阻塞的 我们要知道
默认的open是阻塞式的,如果我们不想阻塞,就要加控制字进去,
有些软件打开就不动了 那就软件设置成是阻塞状态的 这样的特别讨厌
O_SYNC
write阻塞等待底层完成之后再返回应用层
等待写完硬盘才算真正完成
不停地写write是很伤硬盘的,
OS会要凑够多少包给缓冲区再去集中去写,这样效率比较高
O_SYNC 没他,OS只写给缓存区就不管了,为了提升硬件寿命,提高节约化的效率
有他,OS会命令立即写硬件,马上处理,我们不希望硬件等待,我们要把重要的数据立即写入,不等人