LINUX基础知识

目录

标准C库IO函数与LINUX的IO

标准C库IO

虚拟地址空间

LINUX系统IO函数

打开关闭文件

读写打开文件

lseek函数

 stat lstat函数

 dup  dup2


标准C库IO函数与LINUX的IO

标准C库IO

调用fopen函数打开文件,会返回一个FILE指针,该指针里有个fd用来定位要操作的文件,这个fd在进程的内核区保存,由PCB(进程控制块)管理,PCB里有一个数组存储文件描述符,大小默认1024。  前三个文件描述符默认的是绑定当前终端(将当前终端虚拟为一个文件)。

ps:一个文件被打开fopen多次,他的文件描述符是不同的。直到close()才被释放。

标准C库IO函数带有缓冲区,先写进缓冲区,再写进磁盘。

Linux的IO函数没有,直接写进磁盘,所以更适合网络通信。

虚拟地址空间

  受保护的地址 有NULL, nullptr等。

用户要想操作内核区需要调用系统API,执行LINUX的系统调用。 (write,,read....)

mmu内存管理单元会将虚拟地址空间里的数据映射到物理内存。

LINUX系统IO函数

打开关闭文件

int fd = open("a.txt",O_RDONLY); //只读打开文件 返回一个文件描述符 失败=-1
//第二个必选项  是4字节int。
close(fd); 关闭文件 

int fd=open("a.txt",O_RDWR|OCREAT,0777);
//O_RDONLY O_WRONLY O_RDWR互斥   可选项 O_APPEND O_ASYNC O_CREAT 等 
//第三个是8进制的数,表示创建出的新文件的读写权限。 最终权限 mode&~umask(0775)   如0777->0775 抹
//去 group的写权限 umask:抹去某些权限 使赋予权限更合理一点。
umask 可以自己设置。



读写打开文件

int main()
{
    using namespace std;
    
    int fd=open("test.cpp",O_RDONLY);
    if(fd==-1)
        perror("open:");
    int fd2=open("test.txt",O_WRONLY|O_CREAT,0664);
    if(fd2==-1)
        perror("write:");
    char buf[1024]={0};
    int l=0;
    do{
        l=read(fd,buf,sizeof(buf));
        write(fd2,buf,l);
    }while(l>0);

    close(fd);
    close(fd2);

    return 0;
   
}

lseek函数

off_t lseek(int fd, off_t offset, int whence)
 whence:    SEEK_SET 偏移量=文件开始加offset
             SEEK_CUR 偏移量=当前位置+offset
             SEEK_END 偏移量=文件大小+offset

作用:  
1 移动文件指针到头文件        lseek(fd,0,SEEK_SET)
2 获取当前文件指针位置        lseek(fd,0,SEEK_CUR)
3 获取文件长度               lseek(fd,0,SEEK_END)
4 拓展文件长度 如10b->110b   lseek(fd,100,SEEK_END)//   (拓展后写一次才会真正扩大)
//比如下载时先创建一个这么大小的空间,再下载,就不会出现下载到一半空间不够的问题。

 stat lstat函数

命令行:stat 文件名 可以查看文件信息

int stat(const char *pathname, struct stat *statbuf); 将文件信息存入 后面的结构体

   

st_mode&S_IFMT  是真正的文件类型

st_mode& S_IRUSR ==1 ? 等于则user有read权限 S_IWUSR ==1则user有write权限。

实现ll 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <pwd.h>
#include <grp.h>
#include <time.h>

int main()
{
    using namespace std;
    struct stat statbuf;
    stat("test.txt",&statbuf);
    cout<<statbuf.st_uid<<" "<<statbuf.st_size<<endl;
    cout<<getpwuid(statbuf.st_uid)->pw_name<<endl; //user name
    cout<<getgrgid(statbuf.st_gid)->gr_name<<endl; //group name
    cout<<ctime(&statbuf.st_mtime)<<endl;  //最后一次修改时间
}

文件属性操作函数

 int access(const char* pathname,int mode) 判断文件对当前进程是否 mode

        mode: R_OK 读权限  W_OK 写权限   X_OK执行权限   F_OK 是否存在

int chmod (pathname, mode_t mode) 修改权限  

        mode可以直接写入要修改的8进制权限值

int chown(pathname,uid_t owner,gid_t group) 修改所属owner,group

        vim etc/passwd查看用户id 

        vim etc/group查看用户组

        id  用户名 可以查看其 user  goup ...

         sudo  useradd gaogao   添加一个用户gaogao

int truncate(pathname,off_t length)修改文件尺寸至指定大小

目录操作函数

mkdir(pathname,mode_t mode)           mkdir("test.txt",0777)(也会与掩码操作)

rmdir(pathname)        移除某空目录 

rename(oldpath,newpath)重命名

chdir(path) 修改进程当前工作目录为path(绝对路径)          chdir("/home/nowcoder/projects/linuxtest/lesson2");

getcwd(char*buf,size_t size) 获取当前工作目录到buf   

          char buf[502];

          getcwd(buf,sizeof(buf));

目录遍历函数

/* DIR *opendir(const char *name); //打开目录
struct dirent* readdir(DIR*) //  读取目录里的内容
int closedir(DIR*) //关闭目录*/

#include<dirent.h>


//获取目录下所有普通文件个数
int getFileNumber(const char* path)
{
     DIR* dir = opendir(path);
     if(dir==nullptr)
     {
         perror("open");
         exit(0);//直接退出 而非返回
     }
     struct dirent* ptr;
     int totaln=0;
     while((ptr=readdir(dir))!=nullptr)
     {
        char* dname=ptr->d_name;
       // cout<<dname<<endl;
        if(strcmp(dname,".")==0||strcmp(dname,"..")==0)
        {
            continue;
        }
        //判断普通文件或目录
        if(ptr->d_type==DT_DIR)
        {
            char newpath[256];
            sprintf(newpath,"%s/%s",path,dname);
            totaln += getFileNumber(newpath);
        }

        if(ptr->d_type==DT_REG)
            totaln++;

     }
     closedir(dir);
     return totaln;
     
}

 dup  dup2

int dup(int oldfd)  复制文件描述符,指向同一个文件,返回值为fd表中最小的空闲的fd。

int dup2(int oldfd,int newfd) 重定向文件描述符,调用后,newfd对应文件close, newfd指向oldfd对应文件,当值相同,相当什么都没做。 返回的是newfd的fd;

fcntl

int fcntl(int fd,int cmd,.../*arg*/)

cmd:对 fd 如何操作   

               F_DUPFD 复制描述符,返回一个新的文件描述符

               F_GETFL 获取指定文件描述符的flag :O_RDONLY等

               F_SETFL 设置fd状态flag:必选:O_RDONLY等,可选 O_APPEND O_NONBLOCK等

int main(int argc,char* argv[])
{
  nt fd=open("test.txt",O_RDONLY);
    int fd2=fcntl(fd,F_DUPFD);//复制fd
    cout<<fd<<" "<<fd2<<endl;

    int flag=fcntl(fd2,F_GETFL); //获取fd2的flag
    cout<<flag<<endl;
    int fd3=fcntl(fd2,F_SETFL,flag|O_APPEND);//fd2的flag追加O_APPEND

    flag=fcntl(fd2,F_GETFL); //再次获取fd2的flag
    cout<<flag<<endl;
    
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值