Linux 系统函数

Man 2 read 查询read的函数,如果提示找不到,需要安装man的文件

sudo yum install man-pages

1、perror函数打印报错信息;

#include <stdio.h> 
#include <errno.h> 
void perror(const char* s); 
perror("open file failed"); // perror函数用与打印报错信息到控制台,并且带上错误原因。错误原因按照错误变量errno的值来决定 // 是一个枚举值 open file failde: No such file or directory

2、read函数在普通文件和设备文件的阻塞性不同

阻塞和不阻塞不是read的函数属性,而是文件的属性。

设备文件:/dev/tty 标准的输入STDIN_FILENO;

SOCKET 和 pipe这两种文件也是堵塞的。

3、Iseek函数获取文件大小和实现文件拓展

#include <sys/types.h> 
#include <unistd.h> // 依赖以上两个头文件 
off_t lseek(int fd, off_t offset, int whence);

fd 表示要操作的文件描述符

offset是相对于whence(基准)的偏移量

whence 可以是SEEK_SET(文件指针开始),SEEK_CUR(文件指针当前位置) ,SEEK_END为文件指针尾

返回值:文件读写指针距文件开头的字节大小,出错,返回-1

lseek 主要作用是移动文件读写指针,因此还有两个作用:拓展文件和获取文件大小

#include<stdio.h> 
#include<stdlib.h> 
#include<sys/types.h> 
#include<unistd.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
void main() { 
int fd=open("test.txt",O_RDWR); 
if(fd == -1) { 
perror("open test.txt"); 
exit(-1); 
} 
printf("file len:%d \n",lseek(fd,0,SEEK_END)); 
close(fd); 
} 
// lseek(fd,100,SEEK_SET)); 
// wirte(fd, "H", 1); //移动到距离文件开始的100个字节的位置 无论原来源文件大小,实现文件的拓展到101字节。 
// offset 可以为负值,返回的文件大小与ls -ltr看到的是同一个结果

4、stat函数应用与stat_mode属性

stat和lstat都是获取文件属性

#include <sys/stat.h>
#include <unistd.h>
int stat(const char* filename, struct sat* buff);
// 通过文件名称filename获取文件信息,并报错到结构体buff中
struct stat buf;
  stat("/etc/hosts", &buf);
  printf("/etc/hosts file size = %d\n", buf.st_size);

struct stat {
  dev_t     st_dev;    //文件的设备编号
  ino_t     st_ino;    //节点
  mode_t    st_mode;   //文件的类型和存取的权限
  nlink_t    st_nlink;   //连到该文件的硬连接数目,刚建立的文件值为1
  uid_t     st_uid;    //用户ID
  gid_t     st_gid;    //组ID
  dev_t     st_rdev;   //(设备类型)若此文件为设备文件,则为其设备编号
  off_t     st_size;   //文件字节数(文件大小)
  unsigned long st_blksize;  //块大小(文件系统的I/O 缓冲区大小)
  unsigned long st_blocks;  //块数
  time_t    st_atime;   //最后一次访问时间
  time_t    st_mtime;   //最后一次修改时间
  time_t    st_ctime;   //最后一次改变时间(指属性)
};
stat_mode定义了以下多种情况:

    S_IFMT   0170000    文件类型的位遮罩
    S_IFSOCK 0140000    scoket
    S_IFLNK 0120000     符号连接
    S_IFREG 0100000     一般文件
    S_IFBLK 0060000     区块装置
    S_IFDIR 0040000     目录
    S_IFCHR 0020000     字符装置
    S_IFIFO 0010000     先进先出
    S_ISUID 04000     文件的(set user-id on execution)位
    S_ISGID 02000     文件的(set group-id on execution)位
    S_ISVTX 01000     文件的sticky位
    S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限
    S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限
    S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限
    S_IRGRP 00040             用户组具可读取权限
    S_IWGRP 00020             用户组具可写入权限
    S_IXGRP 00010             用户组具可执行权限
    S_IROTH 00004             其他用户具可读取权限
    S_IWOTH 00002             其他用户具可写入权限
    S_IXOTH 00001             其他用户具可执行权限
    上述的文件类型在POSIX中定义了检查这些类型的宏定义:
    S_ISLNK (st_mode)    判断是否为符号连接
    S_ISREG (st_mode)    是否为一般文件
    S_ISDIR (st_mode)    是否为目录
    S_ISCHR (st_mode)    是否为字符装置文件
    S_ISBLK (s3e)        是否为先进先出
    S_ISSOCK (st_mode)   是否为socket

stat_mode属性:文件的类型和存储的权限。

stat(pathName, &sb);
if((sb.st_mode & S_IFMT) == S_IFREG){
    // 普通文件
} else (sb.st_mode & S_IFMT) == S_IFDIR){
    // 目录文件
} else(S_IFLINK(sb.st_mode)) {
    // 链接文件
}
// 判断文件权限
if(sb.st_mode & S_IROTH){
    //可读权限
} else if(sb.st_mode & S_IROTH){
    //可读权限
} else if(sb.st_mode & S_IROTH) {
    // 可写权限
} else if(sb.st_mode & S_IROTH) {
    // 可执行权限
}

5、lstat函数的使用

针对软连接文件而言,lstat函数可以穿透,指向的是本身的文件,而stat函数标识的是指向的文件属性。

6、目录遍历函数

DIR * pDir = opendir("dir"); // 打开目录

while((p=readdir(pDir) != NULL)) // 循环遍历函数

closedir(pDir); //关闭目录;

linux的目录遍历函数:


#include <stdio.h>  
#include <string.h> 
#include <stdlib.h>  
#include <dirent.h>  
#include <sys/stat.h>  
#include <unistd.h>  
#include <sys/types.h> 
using namespace std;
void listDir(char *path)  
{  
        DIR              *pDir ;  
        struct dirent    *ent  ;  
        int               i=0  ;  
        char              childpath[512];  

        pDir=opendir(path);  
        memset(childpath,0,sizeof(childpath));  

  
        while((ent=readdir(pDir))!=NULL)  
        {  

                if(ent->d_type & DT_DIR)  
                {  

                        if(strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)  
                                continue;  

                        sprintf(childpath,"%s/%s",path,ent->d_name);  
                        printf("path:%s/n",childpath);  

                        listDir(childpath);  

                }  
else
{
cout<<ent->d_name<<endl;
}
        }  

}  

int main(int argc,char *argv[])  
{  
        listDir(argv[1]);  
        return 0;  
}

7、dup函数与dup2函数

在linux下,一切皆文件。当文件被打开时,会返回文件描述符用于操作该文件,从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2);)0表示标准输入,1表示标准输出,2表示标准错误。一个进程当前有哪些打开的文件描述符可以通过/proc/进程ID/fd目录查看。

用于复制文件描述符的函数dup和dup2

dup2函数还具有文件重定向的功能。

dup2(fd, STDOUT_FILENO); // 修改了默认的printf的输出路径为fd打开的文件

#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup函数返回当前系统可用的最小整数值。
    dup2函数返回第一个不小于newfd的整数值。也就是分为两种情况:
    ①、如果newfd已经打开,则先将其关闭,再复制文件描述符。
    ②、如果newfd等于oldfd,则dup2返回newfd, 而不关闭它。
//测试dup2函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main()
{
    int fd = open("b.txt", O_RDWR | O_CREAT);
    if(fd == -1)
    {
        perror("open");
        exit(1);
    }

int fd1 = open("a.txt", O_RDWR);
if(fd1 == -1)
{
    perror("open");
    exit(1);
}

printf("fd = %d\n", fd);
printf("fd1 = %d\n", fd1);

int ret = dup2(fd, fd1);  //让fd1和fd同时指向b.txt
if(ret == -1)
{
    perror("dup2");
    exit(1);
}
printf("current fd = %d\n", ret);
char* buf = "hello ";
char* buf1 = " world!";
write(fd, buf, strlen(buf));
write(fd1, buf1 , strlen(buf1));

close(fd);
close(fd1);


return 0;

8、fcntl函数

fcntl函数用于对已经打开的文件描述符进行各种控制操作以及改变已打开文件的各种属性。

#include<unistd.h>
#include<fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd ,struct flock* lock);

(1)F_DUPFD

与dup函数功能一样,复制由fd指向的文件描述符,调用成功后返回新的文件描述符,与旧的文件描述符共同指向同一个文件。

(2)F_GETFD

读取文件描述符close-on-exec标志

(3)F_SETFD

将文件描述符close-on-exec标志设置为第三个参数arg的最后一位

(4)F_GETFL

获取文件打开方式的标志,标志值含义与open调用一致

(5)F_SETF

设置文件打开方式为arg指定方式

文件记录锁是fcntl函数的主要功能。

记录锁:实现只锁文件的某个部分,并且可以灵活的选择是阻塞方式还是立刻返回方式

当fcntl用于管理文件记录锁的操作时,第三个参数指向一个struct flock *lock的结构体

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值