Linux系统编程 40 -open函数

Linux系统编程 40 open函数

学习笔记

函数原型:

int open(const char *pathname, init flags);
int open(const char *pathname, int flags,mode_t mode);
int close(int fd);

 open 成功的时候,会返回一个整数
          失败的时候,会返回-1
      
pathname : 文件路径
flags         : 读写权限
mode        : 用户 用户组 其他用户的权限 八进制形式

权限同时受umask的影响 
文件权限=mode&~umask
           

两个版本的区别:
第一个open用于打开已经存在的文件
第二个open用于打开不存在的文件

      
常用的参数

O_RDONLY 
O_WRONLY
O_RDWR

O_APPEND   防止清空,在末尾添加
O_CREAT
O_EXCL        是否存在
O_TRUNC    把文件截断成0.就是把文件清零
      
O_NONBLOCK  不阻塞


先创建文件      

$touch dict.txt


小细节:

 #include <sys/types.h>
 #include <sys/stat.h>

这两个头文件可以用#include<unistd.h> //#unix stdandard 来替换

$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard 
int main(int argc, char *argv[])
{
    int fd;
    fd = open("./dict.txt",O_RDONLY);
    printf("fd = %d\n",fd);
    close(fd);
    return 0;
}


$gcc open.c -o open
open.c: In function ‘main’:
open.c:10:25: error: ‘O_RDONLY’ undeclared (first use in this function)
  fd = open("./dict.txt",O_RDONLY);
                         ^
open.c:10:25: note: each undeclared identifier is reported only once for each function it appears in


添加头文件

#include<fcontl.h>
$gcc open.c -o open
$./open
fd = 3


打开一个不存在的文件
修改代码如下:

$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard 

#include<fcntl.h>
int main(int argc, char *argv[])
{
    int fd;
    //fd = open("./dict.txt",O_RDONLY);
    fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
    printf("fd = %d\n",fd);
    close(fd);
    return 0;
}

可以看到dict.cpp的权限和设计意图一样。

$gcc open.c -o open
$ls
dict.txt  open  open.c
$./open
fd = 3
$ls
dict.cpp  dict.txt  open  open.c
$ll
total 24
drwxrwxr-x  2 ubuntu ubuntu 4096 Dec 13 22:36 ./
drwxrwxrwx 10 root   root   4096 Dec 13 22:16 ../
-rw-r--r--  1 ubuntu ubuntu    0 Dec 13 22:36 dict.cpp
-rw-rw-r--  1 ubuntu ubuntu    0 Dec 13 22:23 dict.txt
-rwxrwxr-x  1 ubuntu ubuntu 8621 Dec 13 22:36 open*
-rw-rw-r--  1 ubuntu ubuntu  860 Dec 13 22:35 open.c


O_TRUNC 用于清空文件内容

现在在dict.cpp文件中添加内容

$cat dict.cpp
sfajfljlfjasdflas
eerqewr

e
sad
f
asdfdfasdfadsg
as
fs
df
ads
fsad
f
as
gagadsaghfjk
$vi dict.cpp
$ll
total 28
drwxrwxr-x  2 ubuntu ubuntu 4096 Dec 14 08:58 ./
drwxrwxrwx 10 root   root   4096 Dec 13 22:16 ../
-rw-r--r--  1 ubuntu ubuntu  598 Dec 14 08:58 dict.cpp
-rw-rw-r--  1 ubuntu ubuntu    0 Dec 13 22:23 dict.txt
-rwxrwxr-x  1 ubuntu ubuntu 8621 Dec 13 22:36 open*
-rw-rw-r--  1 ubuntu ubuntu  934 Dec 14 08:56 open.c


修改程序 open.c

$vi open.c
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard 

#include<fcntl.h>
int main(int argc, char *argv[])
{
    int fd;
    //fd = open("./dict.txt",O_RDONLY);
    //fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
    fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-
    printf("fd = %d\n",fd);
    close(fd);
    return 0;
}


fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-
这个函数的意思是
1.如果文件不存在,这以指定的权限创建一个文件
2.如果文件存在,以只读方式打开,并截断成0.则该文件清空

$gcc open.c -o open
l$ls
dict.cpp  dict.txt  open  open.c
$./open
fd = 3
$ll
total 24
drwxrwxr-x  2 ubuntu ubuntu 4096 Dec 14 09:01 ./
drwxrwxrwx 10 root   root   4096 Dec 13 22:16 ../
-rw-r--r--  1 ubuntu ubuntu    0 Dec 14 09:01 dict.cpp
-rw-rw-r--  1 ubuntu ubuntu    0 Dec 13 22:23 dict.txt
-rwxrwxr-x  1 ubuntu ubuntu 8621 Dec 14 09:01 open*
-rw-rw-r--  1 ubuntu ubuntu  928 Dec 14 09:00 open.c

文件被清空(没有内容)

$cat dict.cpp
$

查看文件权限 

$umask
0002


修改程序

$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard 

#include<fcntl.h>
int main(int argc, char *argv[])
{
    int fd;
    //fd = open("./dict.txt",O_RDONLY);
    //fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r--r--
 //    fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r--r--

     fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwxrwxrwx
    printf("fd = %d\n",fd);
    close(fd);
    return 0;
}
$gcc open.c -o open
$ls
dict.cpp  dict.txt  open  open.c
$./open
fd = 3
$ls
dict.cp2  dict.cpp  dict.txt  open  open.c
$ll
total 24
drwxrwxr-x  2 ubuntu ubuntu 4096 Dec 14 12:43 ./
drwxrwxrwx 10 root   root   4096 Dec 13 22:16 ../
-rwxrwxr-x  1 ubuntu ubuntu    0 Dec 14 12:43 dict.cp2*
-rw-r--r--  1 ubuntu ubuntu    0 Dec 14 09:01 dict.cpp
-rw-rw-r--  1 ubuntu ubuntu    0 Dec 13 22:23 dict.txt
-rwxrwxr-x  1 ubuntu ubuntu 8621 Dec 14 12:43 open*
-rw-rw-r--  1 ubuntu ubuntu 1007 Dec 14 12:42 open.c


777&(~002)=775  rwxrwx-wx 符合设计意图

open常见的错误

1.打开的文件不存在,返回值为-1

$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard 
#include<errno.h>
#include<fcntl.h>
int main(int argc, char *argv[])
{
    int fd;
    //fd = open("./dict.txt",O_RDONLY);
    //fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
 //    fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-

     //fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwx -rwx-wxr-
    
     fd = open("./dict.cp4",O_RDONLY);
    printf("fd = %d errno=%d\n",fd,errno);
    close(fd);
    return 0;
}

$gcc open.c -o open
$./open
fd = -1 errno=2

errno =2的含义可以通过
char *strerror(int errnum);(要加string.h)翻译出来

$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard 
#include<errno.h>
#include<fcntl.h>
int main(int argc, char *argv[])
{
    int fd;
    //fd = open("./dict.txt",O_RDONLY);
    //fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
 //    fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-

     //fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwx -rwx-wxr-
    
     fd = open("./dict.cp4",O_RDONLY);
    printf("fd = %d errno=%d %s \n",fd,errno,strerror(errno));
    close(fd);
    return 0;
}
$gcc open.c -o open
$./open
fd = -1 errno=2 No such file or directory 


2.以写方式打开只读文件(打开文件没有对应的权限)

$touch dict.cp3
$ll
total 24
drwxrwxr-x  2 ubuntu ubuntu 4096 Dec 14 12:59 ./
drwxrwxrwx 10 root   root   4096 Dec 13 22:16 ../
-rwxrwxr-x  1 ubuntu ubuntu    0 Dec 14 12:43 dict.cp2*
-rw-rw-r--  1 ubuntu ubuntu    0 Dec 14 12:59 dict.cp3
-rw-r--r--  1 ubuntu ubuntu    0 Dec 14 09:01 dict.cpp
-rw-rw-r--  1 ubuntu ubuntu    0 Dec 13 22:23 dict.txt
-rwxrwxr-x  1 ubuntu ubuntu 8737 Dec 14 12:57 open*
-rw-rw-r--  1 ubuntu ubuntu 1102 Dec 14 12:56 open.c
$chmod u-w dict.cp3
$ll
total 24
drwxrwxr-x  2 ubuntu ubuntu 4096 Dec 14 12:59 ./
drwxrwxrwx 10 root   root   4096 Dec 13 22:16 ../
-rwxrwxr-x  1 ubuntu ubuntu    0 Dec 14 12:43 dict.cp2*
-r--rw-r--  1 ubuntu ubuntu    0 Dec 14 12:59 dict.cp3
-rw-r--r--  1 ubuntu ubuntu    0 Dec 14 09:01 dict.cpp
-rw-rw-r--  1 ubuntu ubuntu    0 Dec 13 22:23 dict.txt
-rwxrwxr-x  1 ubuntu ubuntu 8737 Dec 14 12:57 open*
-rw-rw-r--  1 ubuntu ubuntu 1102 Dec 14 12:56 open.c
$vim open.c
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard 
#include<errno.h>
#include<fcntl.h>
int main(int argc, char *argv[])
{
    int fd;
    //fd = open("./dict.txt",O_RDONLY);
    //fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
    //    fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-

    //fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwx -rwx-wxr-

    //fd = open("./dict.cp4",O_RDONLY);
    fd = open("./dict.cp3",O_WRONLY);
    printf("fd = %d errno=%d %s \n",fd,errno,strerror(errno));
    close(fd);
    return 0;
}
$gcc open.c -o open
$./open
fd = -1 errno=13 Permission denied 
$

3.以只写方式打开目录

程序为

$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard 
#include<errno.h>
#include<fcntl.h>
int main(int argc, char *argv[])
{
    int fd;
    //fd = open("./dict.txt",O_RDONLY);
    //fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
    //    fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-

    //fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwx -rwx-wxr-

    //fd = open("./dict.cp4",O_RDONLY);
    //fd = open("./dict.cp3",O_WRONLY);
    fd = open("./mydir",O_WRONLY);
    printf("fd = %d errno=%d %s \n",fd,errno,strerror(errno));
    close(fd);
    return 0;
}
$mkdir mydir
$vim open.c
$gcc open.c -o open
$./open
fd = -1 errno=21 Is a directory 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值