博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
文件与I/O
阅读量:2185 次
发布时间:2019-05-02

本文共 11393 字,大约阅读时间需要 37 分钟。

文件和I/O

STDIN_FILENO     stdin

STDOUT_FILENO   stdout

STDERROR_FILENO stderr

一、文件描述符

q 对于Linux而言,所有对设备或文件的操作都是通过文件描述符进行的。

q 当打开或者创建一个文件的时候,内核向进程返回一个文件描述符(非负整数)。后续对文件的操作只需通过该文件描述符,内核记录有关这个打开文件的信息。

q 一个进程启动时,默认打开了3个文件,标准输入、标准输出、标准错误,对应文件描述符是0STDIN_FILENO)、1STDOUT_FILENO)、2STDERR_FILENO,这些常量定义在unistd.h头文件中。

二、文件描述符与文件指针转换

fileno:将文件指针转换为文件描述符

fdopen:将文件描述符转换为文件指针

//01fileno.c

#include<stdio.h>

#include<stdlib.h>

intmain()

{

         printf(“fileno(stdin):%d\n”,fileno(stdin));

 

         return 0;

}

三、open函数

//01open.c

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

/*

#defineERR_EXIT(m) (perror(m), exit(EXIT_FAILURE))

*/

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(void)

{

         int fd;

         fd = open("test.txt",O_RDONLY);

/*

         if (fd == -1)

         {

                   fprintf(stderr, "openerror with errno=%d %s\n", errno, strerror(errno));

                   exit(EXIT_FAILURE);

         }

*/

/*

         if (fd == -1)

         {

                   perror("openerror");

                   exit(EXIT_FAILURE);

         }

*/

         if (fd == -1)

                   ERR_EXIT("openerror");

 

         printf("open succ\n");

         return 0;

}

 

 

//02open.c

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(void)

{

         umask(0);

         int fd;

         fd = open("test.txt",O_WRONLY |O_CREAT, 0666);

         if (fd == -1)

                   ERR_EXIT("openerror");

 

         printf("open succ\n");

         return 0;

}

 

//03open.c

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(void)

{

         umask(0);

         int fd;

         fd = open("test.txt",O_WRONLY | O_CREAT |O_EXCL, 0666);

         if (fd == -1)

                   ERR_EXIT("openerror");

 

         printf("open succ\n");

         return 0;

}

 

//04open.c

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

int main(void)

{

         umask(0);

         int fd;

         fd = open("test2.txt",O_WRONLY | O_CREAT | O_EXCL,S_IRUSR |S_IWUSR);

         if (fd == -1)

                   ERR_EXIT("openerror");

 

         printf("open succ\n");

         close(fd);

         return 0;

}

 

四、man 2 open查看相关的属性

1、打开文件的方式

2、访问权限

打开方式

描述

S_IRUSR

文件所有者的读权限位

S_IWUSR

文件所有者的写权限位

S_IXUSR

文件所有者的执行权限位

S_IRWXU

S_IRUSR|S_IWUSR|S_IXUSR

S_IRGRP

文件用户组的读权限位

S_IWGRP

文件用户组的写权限位

S_IXGRP

文件用户组的执行权限位

S_IRWXG

S_IRGRP|S_IWGRP|S_IXGRP

S_IROTH

文件其他用户的读权限位

S_IWOTH

文件其他用户的写权限位

S_IXOTH

文件其他用户的执行权限位

S_IRWXO

S_IROTH|S_IWOTH|S_IXOTH

五、open调用的几点说明

q 可以利用按位逻辑加(bitwise-OR)(|)对打开方式的标志值进行组合。

        如打开一个新文件:

         define NEWFILE (O_WRONLY|O_CREAT|O_TRUNC)

q 对访问权限位进行访问所用到的标识符,均可以通过

         include <sys/stat.h>访问到,同样可以通过|运算来对访问权限进行组合

         #define MODE755   (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)

六、close系统调用

q 为了重新利用文件描述符,用close()系统调用释放打开的文件描述符

函数原型:int close(int fd);

函数参数:

-    fd :要关闭的文件的文件描述符

返回值

         如果出现错误,返回-1

         调用成功返回0

七、read系统调用

q 一旦有了与一个打开文件描述相连的文件描述符,只要该文件是用O_RDONLYO_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节

q 函数原型:

                   ssize_t read(int fd, void*buf, size_t count);

                  参数

fd:想要读的文件的文件描述符

buf:指向内存块的指针,从文件中读取来的字节放到这个内存块中

count:从该文件复制到buf中的字节个数

返回值

         如果出现错误,返回-1

         读文件结束,返回0

         否则返回从该文件复制到规定的缓冲区中的字节数

八、write系统调用

q 用write()系统调用将数据写到一个文件中

函数原型:

ssize_twrite(int fd, const void *buf, size_t count);

函数参数:

-    fd:要写入的文件的文件描述符

-    buf:指向内存块的指针,从这个内存块中读取数据写入       到文件中

-    count:要写入文件的字节个数

返回值

         如果出现错误,返回-1

         如果写入成功,则返回写入到文件中的字节个数

 

//01cp.c

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(int argc, char *argv[])

{

         int infd;

         int outfd;

         if (argc != 3)

         {

                   fprintf(stderr, "Usage%s src dest\n", argv[0]);

                   exit(EXIT_FAILURE);

         }

 

         infd = open(argv[1], O_RDONLY);

         if (infd == -1)

                   ERR_EXIT("open srcerror");

 

         if ((outfd = open(argv[2], O_WRONLY |O_CREAT | O_TRUNC, 0644)) == -1)

                   ERR_EXIT("open desterror");

        

         char buf[1024];

         int nread;

         while ((nread = read(infd, buf, 1024))> 0)

         {

                   write(outfd, buf, nread);

         }

 

         close(infd);

         close(outfd);

         return 0;

}

 

read可以保证一定能读到缓冲区

write不能保证一定能从缓冲区写到文件中,除非调用int fsync(int fd)函数或在打开文件时指定O_SYNC

九、lseek调用

//01lseek.c

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(void)

{

         int fd;

         fd = open("test.txt",O_RDONLY);

         if (fd == -1)

                   ERR_EXIT("openerror");

 

         char buf[1024] = {0};

         int ret = read(fd, buf, 5);

         if (ret == -1)

                   ERR_EXIT("readerror");

         printf("buf=%s\n", buf);

        

         ret = lseek(fd, 0, SEEK_CUR);

         if (ret == -1)

                   ERR_EXIT("lseek");

 

         printf("current offset=%d\n",ret);

         return 0;

        

}

 

//03hole.c

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(void)

{

         int fd;

         fd = open("hole.txt",O_WRONLY | O_CREAT | O_TRUNC, 0644);

         if (fd == -1)

                   ERR_EXIT("openerror");

 

         write(fd, "ABCDE", 5);

 

         int ret = lseek(fd, 32, SEEK_CUR);

         if (ret == -1)

                   ERR_EXIT("lseekerror");

 

         write(fd, "hello", 5);

 

         close(fd);

 

         return 0;

}

man lseek

od –chole.txt  查看hole.txt在内存中的使用情况

du –hhole.txt  查看hole.txt在磁盘占用的情况

 

十、opendirreaddir调用

#include<unistd.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

#include<dirent.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(void)

{

         DIR *dir = opendir(".");

         struct dirent *de;

         while ((de = readdir(dir)) != NULL)

         {

                   if (strncmp(de->d_name,".", 1) == 0)

                            continue;

 

                   printf("%s\n",de->d_name);

         }

 

         closedir(dir);

         exit(EXIT_SUCCESS);

}

 

十一、stat函数

#include<unistd.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

#defineMAJOR(a) (int)((unsigned short)a >> 8)

#defineMINOR(a) (int)((unsigned short)a & 0xFF)

 

intfiletype(struct stat *buf);

voidfileperm(struct stat *buf, char *perm);

 

intmain(int argc, char *argv[])

{

         if (argc != 2)

         {

                   fprintf(stderr, "Usage%s file\n", argv[0]);

                   exit(EXIT_FAILURE);

         }

 

         struct stat sbuf;

         printf("Filename:%s\n",argv[1]);

         if (lstat(argv[1], &sbuf) == -1)

                   ERR_EXIT("staterror");

 

         printf("File number:major %d,minor%d inode %d\n", MAJOR(sbuf.st_dev), MINOR(sbuf.st_dev), (int)sbuf.st_ino);

         if (filetype(&sbuf))

         {

                   printf("Devicenumber:major %d,minor %d\n", MAJOR(sbuf.st_rdev), MINOR(sbuf.st_rdev));

         }

        

         char perm[11] = {0};

         fileperm(&sbuf, perm);

         printf("File permission bits=%o%s\n", sbuf.st_mode & 07777, perm);

        

 

         return 0;

}

 

 

intfiletype(struct stat *buf)

{

         int flag = 0;

         printf("Filetype:");

         mode_t mode;

         mode = buf->st_mode;

         switch (mode & S_IFMT)

         {

         case S_IFSOCK:

                   printf("socket\n");

                   break;

         case S_IFLNK:

                   printf("symboliclink\n");

                   break;

         case S_IFREG:

                   printf("regularfile\n");

                   break;

         case S_IFBLK:

                   printf("blockdevice\n");

                   flag = 1;

                   break;

         case S_IFDIR:

                   printf("directory\n");

                   break;

         case S_IFCHR:

                   printf("characterdevice\n");

                   flag = 1;

                   break;

         case S_IFIFO:

                   printf("FIFO\n");

                   break;

         default:

                   printf("unknown filetype\n");

                   break;

         }

 

         return flag;

}

 

voidfileperm(struct stat *buf, char *perm)

{

         strcpy(perm, "----------");

         perm[0] = '?';

         mode_t mode;

        mode = buf->st_mode;

        switch (mode & S_IFMT)

        {

        case S_IFSOCK:

                   perm[0] = 's';

                break;

        case S_IFLNK:

                   perm[0] = 'l';

                break;

        case S_IFREG:

                   perm[0] = '-';

                break;

        case S_IFBLK:

                   perm[0] = 'b';

                break;

        case S_IFDIR:

                   perm[0] = 'd';

                break;

        case S_IFCHR:

                   perm[0] = 'c';

                break;

         case S_IFIFO:

                   perm[0] = 'p';

                break;

         }

 

         if (mode & S_IRUSR)

                   perm[1] = 'r';

         if (mode & S_IWUSR)

                   perm[2] = 'w';

         if (mode & S_IXUSR)

                   perm[3] = 'x';

         if (mode & S_IRGRP)

                   perm[4] = 'r';

         if (mode & S_IWGRP)

                   perm[5] = 'w';

         if (mode & S_IXGRP)

                   perm[6] = 'x';

         if (mode & S_IROTH)

                   perm[7] = 'r';

         if (mode & S_IWOTH)

                   perm[8] = 'w';

         if (mode & S_IXOTH)

                   perm[9] = 'x';

         perm[10] = '\0';

}

 

十二、一个进程打开两个文件

#include<unistd.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(int argc, char *argv[])

{

         int fd1;

         int fd2;

         char buf1[1024] = {0};

         char buf2[1024] = {0};

         fd1 = open("test.txt",O_RDONLY);

         if (fd1 == -1)

                   ERR_EXIT("openerror");

         read(fd1, buf1, 5);

         printf("buf1=%s\n", buf1);

        

 

         fd2 = open("test.txt",O_RDWR);

         if (fd2 == -1)

                   ERR_EXIT("openerror");

 

         read(fd2, buf2, 5);

         printf("buf2=%s\n", buf2);

         write(fd2, "AAAAA", 5);

 

         memset(buf1, 0, sizeof(buf1));

         read(fd1, buf1, 5);

         printf("buf1=%s\n", buf1);

         close(fd1);

         close(fd2);

         return 0;

}

十三、dupdup2fcntl进行输出重定向

#include<unistd.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(int argc, char *argv[])

{

         int fd;

         fd = open("test2.txt",O_WRONLY);

         if (fd == -1)

                   ERR_EXIT("openerror");

 

/*

         close(1);

         dup(fd);

*/

/*

         dup2(fd, 1);

*/

close(1);

         if (fcntl(fd, F_DUPFD, 0) < 0)

                   ERR_EXIT("dup fderror");

         printf("hello\n");

         return 0;

}

 

十四、文件状态标志

#include<unistd.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

voidset_flag(int fd, int flags);

voidclr_flag(int fd, int flags);

 

intmain(int argc, char *argv[])

{

         char buf[1024] = {0};

         int ret;

/*

         int flags;

         flags = fcntl(0, F_GETFL, 0);

         if (flags == -1)

                   ERR_EXIT("fcntl get flagerror");

 

         ret = fcntl(0, F_SETFL, flags |O_NONBLOCK);

         if (ret == -1)

                   ERR_EXIT("fcntl set flagerror");

*/

         set_flag(0, O_NONBLOCK);

         clr_flag(0, O_NONBLOCK);

         ret = read(0, buf, 1024);

         if (ret == -1)

                   ERR_EXIT("readerror");

 

         printf("buf=%s\n", buf);

         return 0;

}

 

voidset_flag(int fd, int flags)

{

         int val;

         val = fcntl(fd, F_GETFL, 0);

         if (val == -1)

                ERR_EXIT("fcntl get flagerror");

         val |= flags;

         if (fcntl(fd, F_SETFL, val) < 0)

                   ERR_EXIT("fcntl set flagerror");

}

 

voidclr_flag(int fd, int flags)

{

         int val;

         val = fcntl(fd, F_GETFL, 0);

         if (val == -1)

                ERR_EXIT("fcntl get flagerror");

         val &= ~flags;

         if (fcntl(fd, F_SETFL, val) < 0)

                   ERR_EXIT("fcntl set flagerror");

}

 

十五、文件锁(注意F_SETLKF_SETLKW的区别)

#include<unistd.h>

#include<sys/stat.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

 

#include<stdlib.h>

#include<stdio.h>

#include<errno.h>

#include<string.h>

 

 

#defineERR_EXIT(m) \

         do \

         { \

                   perror(m); \

                   exit(EXIT_FAILURE); \

         } while(0)

 

intmain(int argc, char *argv[])

{

         int fd;

         fd = open("test2.txt",O_CREAT | O_RDWR | O_TRUNC, 0644);

         if (fd == -1)

                   ERR_EXIT("openerror");

 

         struct flock lock;

         memset(&lock, 0, sizeof(lock));

         lock.l_type = F_WRLCK;

         lock.l_whence = SEEK_SET;

         lock.l_start = 0;

         lock.l_len = 0;

 

         /*if (fcntl(fd, F_SETLK, &lock) ==0)*/

         if (fcntl(fd, F_SETLKW, &lock) ==0)

         {

                   printf("locksuccess\n");

                   printf("press any key tounlock\n");

                   getchar();

                   lock.l_type = F_UNLCK;

                   if (fcntl(fd, F_SETLK,&lock) == 0)

                            printf("unlocksuccess\n");

                   else

                            ERR_EXIT("unlockfail");

         }

         else

                   ERR_EXIT("lockfail");

 

         return 0;

}

转载地址:http://dahkb.baihongyu.com/

你可能感兴趣的文章
【JS】【31】读取json文件
查看>>
OpenSSL源代码学习[转]
查看>>
Spring下载地址
查看>>
google app api相关(商用)
查看>>
linux放音乐cd
查看>>
GridView+存储过程实现'真分页'
查看>>
flask_migrate
查看>>
解决activemq多消费者并发处理
查看>>
UDP连接和TCP连接的异同
查看>>
hibernate 时间段查询
查看>>
java操作cookie 实现两周内自动登录
查看>>
Tomcat 7优化前及优化后的性能对比
查看>>
Java Guava中的函数式编程讲解
查看>>
Eclipse Memory Analyzer 使用技巧
查看>>
tomcat连接超时
查看>>
谈谈编程思想
查看>>
iOS MapKit导航及地理转码辅助类
查看>>
检测iOS的网络可用性并打开网络设置
查看>>
简单封装FMDB操作sqlite的模板
查看>>
iOS开发中Instruments的用法
查看>>