代码编织梦想

目录

01. 学习目标

02. 文件操作相关函数

2.1 stat函数(重点)

2.2 access函数

2.4 chown函数

2.5 truncate函数

2.6 link函数

2.7 symlink函数

2.8 readlink函数

2.9 unlink函数

2.10 rename函数

03. 文件描述符复制(重点)

3.1 概述

3.1 dup函数

3.3 示例分析

04. fcnlt函数

05. 目录相关操作(掌握)

5.1 getcwd函数

5.2 chdir函数

5.3 opendir函数

5.4 closedir函数

5.5 readdir函数

06. 时间相关函数

相关源代码:

open.c

close.c

read.c

copy.c

unbock.c

lseek.c

stat.c

stat1.c

access.c

symlinc.c

dup.c

dup2.c

fcntl.c

 fcntl.c


01. 学习目标

  • 了解概念: pcb和文件描述符,虚拟地址空间
  • 了解Linux系统常用IO函数(暂不要求能够使用)
  • 熟练掌握Linux系统IO函数的使用
  • 了解阻塞和非阻塞的概念
  • 掌握dup、dup2函数的使用
  • 熟练掌握Linux系统IO函数的使用
  • 掌握stat/lstat函数的使用
  • 掌握fcntl函数的使用

02. 文件操作相关函数

2.1 stat函数(重点)

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
​
int stat(const char *path, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
功能:
    获取文件状态信息
    stat和lstat的区别:
        当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;
        而stat返回的是该链接指向的文件的信息。
参数:
    path:文件名
    buf:保存文件信息的结构体
返回值:
    成功: 0
    失败: -1

struct stat结构体说明:

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;        //文件字节数(文件大小)
    blksize_t       st_blksize;     //块大小(文件系统的I/O 缓冲区大小)
    blkcnt_t        st_blocks;      //块数
    time_t          st_atime;       //最后一次访问时间
    time_t          st_mtime;       //最后一次修改时间
    time_t          st_ctime;       //最后一次改变时间(指属性)
};

st_mode(16位整数)参数说明

文件类型判断应使用宏函数

测试程序:

int main()
{
    struct stat buf;
    stat("a.txt", &buf);
​
    if (S_ISREG(buf.st_mode))
    {
        printf("%s\n", "这是普通文件");
    }
​
    return 0;
}

2.2 access函数

#include <unistd.h>
​
int access(const char *pathname, int mode);
功能:测试指定文件是否具有某种属性
参数:
    pathname:文件名
    mode:文件权限,4种权限
        R_OK:   是否有读权限
        W_OK:   是否有写权限
        X_OK:   是否有执行权限
        F_OK:   测试文件是否存在
返回值:
    0:  有某种权限,或者文件存在
    -1:没有,或文件不存在
access("txt", F_OK);

2.3 chmod函数


#include <sys/stat.h>
​
int chmod(const char *pathname, mode_t mode);
功能:修改文件权限
参数:
    filename:文件名
    mode:权限(8进制数)
返回值:
    成功:0
    失败:-1

2.4 chown函数

#include <unistd.h>
​
int chown(const char *pathname, uid_t owner, gid_t group);
功能:修改文件所有者和所属组
参数:
    pathname:文件或目录名
    owner:文件所有者id,通过查看 /etc/passwd 得到所有者id
    group:文件所属组id,通过查看 /etc/group 得到用户组id
返回值:
    成功:0
    失败:-1

2.5 truncate函数

#include <unistd.h>
#include <sys/types.h>
​
int truncate(const char *path, off_t length);
功能:修改文件大小
参数:
    path:文件文件名字
    length:指定的文件大小
        a)比原来小, 删掉后边的部分
        b)比原来大, 向后拓展
返回值:
    成功:0
    失败:-1

2.6 link函数

#include <unistd.h>
​
int link(const char *oldpath, const char *newpath);
功能:创建一个硬链接
参数:
    oldpath:源文件名字
    newpath:硬链接名字
返回值:
    成功:0
    失败:-1

2.7 symlink函数

#include <unistd.h>
​
int symlink(const char *target, const char *linkpath);
功能:创建一个软链接
参数:
    target:源文件名字
    linkpath:软链接名字
返回值:
    成功:0
    失败:-1

2.8 readlink函数

2.9 unlink函数

#include <unistd.h>
​
int unlink(const char *pathname);
功能:删除一个文件(软硬链接文件)
参数:
    pathname:删除的文件名字
返回值:
    成功:0
    失败:-1

2.10 rename函数

#include <stdio.h>
​
int rename(const char *oldpath, const char *newpath);
功能:把oldpath的文件名改为newpath
参数:
oldpath:旧文件名
newpath:新文件名
返回值:
成功:0
失败:-1

03. 文件描述符复制(重点)

3.1 概述

dup() 和 dup2() 是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。

这个过程类似于现实生活中的配钥匙,钥匙相当于文件描述符,锁相当于文件,本来一个钥匙开一把锁,相当于,一个文件描述符对应一个文件,现在,我们去配钥匙,通过旧的钥匙复制了一把新的钥匙,这样的话,旧的钥匙和新的钥匙都能开启这把锁。

对比于 dup(), dup2() 也一样,通过原来的文件描述符复制出一个新的文件描述符,这样的话,原来的文件描述符和新的文件描述符都指向同一个文件,我们操作这两个文件描述符的任何一个,都能操作它所对应的文件。

3.1 dup函数

#include <unistd.h>
​
int dup(int oldfd);
功能:
    通过 oldfd 复制出一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描述符,最终 oldfd 和新的文件描述符都指向同一个文件。
参数:
    oldfd : 需要复制的文件描述符 oldfd
返回值:
        成功:新文件描述符
        失败: -1

3.2 dup2函数

#include <unistd.h>
​
int dup2(int oldfd, int newfd);
功能:
    通过 oldfd 复制出一个新的文件描述符 newfd,如果成功,newfd 和函数返回值是同一个返回值,最终 oldfd 和新的文件描述符 newfd 都指向同一个文件。
参数:
    oldfd : 需要复制的文件描述符
    newfd : 新的文件描述符,这个描述符可以人为指定一个合法数字(0 - 1023),如果指定的数字已经被占用(和某个文件有关联),此函数会自动关闭 close() 断开这个数字和某个文件的关联,再来使用这个合法数字。
返回值:
    成功:返回 newfd
    失败:返回 -1

3.3 示例分析

04. fcnlt函数

#include <unistd.h>
#include <fcntl.h>
​
int fcntl(int fd, int cmd, ... /* arg */);
功能:改变已打开的文件性质,fcntl针对描述符提供控制。
参数:
    fd:操作的文件描述符
    cmd:操作方式
    arg:针对cmd的值,fcntl能够接受第三个参数int arg。
返回值:
    成功:返回某个其他值
    失败:-1

fcntl函数有5种功能:

1) 复制一个现有的描述符(cmd=F_DUPFD)

2) 获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)

3) 获得/设置文件状态标记(cmd=F_GETFL或F_SETFL)

4) 获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)

5) 获得/设置记录锁(cmd=F_GETLK, F_SETLK或F_SETLKW)

参考示例:

// 等价于dup()
    int new_fd = fcntl(fd, F_DUPFD, 0);
​
    // 获取文件状态标志
    int flag = fcntl(fd, F_GETFL, 0);
    switch (flag & O_ACCMODE)
    {
    case O_RDONLY:
        printf("read only\n");
        break;
    case O_WRONLY:
        printf("write only\n");
        break;
    case O_RDWR:
        printf("read and write\n");
        break;
    default:
        break;
    }
​
    if (flag & O_APPEND)
    {
        printf("append\n");
    }
​
    flag |= O_APPEND; // 追加flag
    fcntl(fd, F_SETFL, flag); //设置文件状态标记

05. 目录相关操作(掌握)

5.1 getcwd函数

#include <unistd.h>
​
char *getcwd(char *buf, size_t size);
功能:获取当前进程的工作目录
参数:
    buf : 缓冲区,存储当前的工作目录
    size : 缓冲区大小
返回值:
    成功:buf中保存当前进程工作目录位置
    失败:NULL

5.2 chdir函数

#include <unistd.h>
​
int chdir(const char *path);
功能:修改当前进程(应用程序)的路径
参数:
    path:切换的路径
返回值:
    成功:0
    失败:-1

5.3 opendir函数

#include <sys/types.h>
#include <dirent.h>
​
DIR *opendir(const char *name);
功能:打开一个目录
参数:
    name:目录名
返回值:
    成功:返回指向该目录结构体指针
    失败:NULL

5.4 closedir函数

#include <sys/types.h>
#include <dirent.h>
​
int closedir(DIR *dirp);
功能:关闭目录
参数:
    dirp:opendir返回的指针
返回值:
    成功:0
    失败:-1

5.5 readdir函数

#include <dirent.h>
​
struct dirent *readdir(DIR *dirp);
功能:读取目录
参数:
    dirp:opendir的返回值
返回值:
    成功:目录结构体指针
    失败:NULL

d_type文件类型说明:

取值含义
DT_BLK块设备
DT_CHR字符设备
DT_DIR目录
DT_LNK软链接
DT_FIFO管道
DT_REG普通文件
DT_SOCK套接字
DT_UNKNOWN未知

06. 时间相关函数

  char *asctime(const struct tm *tm);
   char *asctime_r(const struct tm *tm, char *buf);
​
   char *ctime(const time_t *timep);
   char *ctime_r(const time_t *timep, char *buf);
​
   struct tm *gmtime(const time_t *timep);
   struct tm *gmtime_r(const time_t *timep, struct tm *result);
​
   struct tm *localtime(const time_t *timep);
   struct tm *localtime_r(const time_t *timep, struct tm *result);
​
   time_t mktime(struct tm *tm);

相关源代码:

open.c

#include <stdio.h>

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



int main(void)
{
    int fd = -1;

    //1.以只读方式打开一个文件  如果文件不存在就报错
    //fd = open("txt", O_RDONLY);
    //2.以只写的方式打开一个文件 如果文件不存在就报错
    //fd = open("txt", O_WRONLY);
    //3.以只写的方式打开一个文件 如果文件不存在就创建, 如果文件存在就直接打开
    //fd = open("txt", O_WRONLY | O_CREAT, 0644);
    //4.以只读的方式打开一个文件 如果文件不存在就创建
    //fd = open("txt", O_RDONLY | O_CREAT, 0644);
    //5.以读写的方式打开文件 如果文件存在就报错, 如果文件不存在就创建
    //fd = open("txt", O_RDWR | O_CREAT | O_EXCL, 0644);
    //6.以读写的方式打开一个文件 如果文件不存在就创建 如果文件存在就清零
    fd = open("txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }


    printf("打开文件成功....\n");


    return 0;
}

close.c

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



#if 0
/* Standard file descriptors.  */
#define	STDIN_FILENO	0	/* Standard input.  */
#define	STDOUT_FILENO	1	/* Standard output.  */
#define	STDERR_FILENO	2	/* Standard error output.  */
#endif

int main(void)
{
    int fd = -1; 

    //1. 打开文件
    fd = open("txt", O_RDWR | O_CREAT, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }


    printf("fd = %d\n", fd);
    printf("打开文件成功....\n");

    //2. 关闭文件 释放资源
    close(fd);

    return 0;
}

read.c

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

#define SIZE 128

int main(void)
{
    int fd = -1;
    int ret = -1;
    char buf[SIZE];

    //1. 打开文件
    fd = open("passwd", O_RDONLY);    
    if (-1 == fd)
    {
        perror("open"); 
        goto err0;
    }

    printf("打开文件ok... fd: %d\n", fd);

    //2. 循环读取数据
    while(1)
    {
        memset(buf, 0, SIZE);
        //每一次从文件中读取最多SIZE个字节
        ret = read(fd, buf, SIZE - 1); 
        if (ret < 0)
        {
            perror("read");
            break; 
        }
    
        printf("%s", buf);
    
        //读到文件结尾
        if (ret < SIZE - 1)
        {
            break; 
        }
    }

    //3. 关闭文件
    close(fd);

    return 0;
err0:
    return 1;
}

copy.c

#include <stdio.h>
#include <string.h>

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

#define SIZE 128

//文件的简单拷贝 支持二进制
int main(int argc, char **argv)
{
    int fdr = -1;
    int fdw = -1;
    int ret = -1;

    char buf[SIZE];

    //容错判断
    if (3 != argc)
    {
        printf("usage: ./a.out filename1 filename2\n"); 
        goto err0;
    }

    //1. 以只读的方式打开第一个文件
    fdr = open(argv[1], O_RDONLY);
    if (-1 == fdr)
    {
        perror("open"); 
        goto err0;
    }

    //2. 以只写的方式打开第二个文件
    fdw = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (-1 == fdw)
    {
        perror("open"); 
        goto err1;
    }

    //3. 循环拷贝数据
    while(1)
    {
        //从第一个文件中读取数据
        memset(buf, 0, SIZE);
        ret = read(fdr, buf, SIZE); 
        if (ret <= 0)
        {
            break; 
        }
    
        //将读取的数据写入到第二个文件中
        ret = write(fdw, buf, ret); 
        if (ret <= 0)
        {
            break; 
        }
    }

    //4. 关闭两个文件描述符
    close(fdr);
    close(fdw);

    return 0;
err1:
    close(fdr);
err0:
    return 1;
}

unbock.c

#include <stdio.h>
#include <string.h>

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

#define SIZE 128



int main(void)
{
    int fd = -1;
    int ret = -1;

    char buf[SIZE];

    //1. 打开一个终端设备  该设备默认是阻塞的
    //fd = open("/dev/tty", O_RDWR);
    fd = open("/dev/tty", O_RDWR | O_NONBLOCK);
    if (-1 == fd)
    {
        perror("open"); 
        goto err0;
    }

    //2. 读设备
    memset(buf, 0, SIZE);
    ret = read(fd, buf, SIZE);
    if (ret <= 0)
    {
        perror("read"); 
    }

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

    //3. 关闭文件
    close(fd);

    return 0;
err0:
    return 1;
}

lseek.c

#include <stdio.h>
#include <string.h>

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

#define SIZE 128

//以十六进制的方式查看文件内容
//deng@itcast:~/share/4th$ od -x txt

int main(void)
{
    int fd = -1;
    int ret = -1;

    //1. 打开文件
    fd = open("txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        goto err1;
    }

    //在文件开头写七个字符
    write(fd, "ABCDEFG",  7);

    //将文件偏移30个字节
    ret = lseek(fd, 1024 * 1024, SEEK_END);
    if (-1 == ret)
    {
        perror("lseek"); 
        goto err2;
    }

    write(fd, "123456789", 9);

    //获取文件的大小
    printf("file: %ld\n", lseek(fd, 0, SEEK_END));

    //关闭文件
    close(fd);

    return 0;
err2:
    close(fd);
err1:
    return 1;
}

stat.c

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

#if 0
struct stat {
    dev_t     st_dev;         /* ID of device containing file */
    ino_t     st_ino;         /* inode number */
    mode_t    st_mode;        /* protection */
    nlink_t   st_nlink;       /* number of hard links */
    uid_t     st_uid;         /* user ID of owner */
    gid_t     st_gid;         /* group ID of owner */
    dev_t     st_rdev;        /* device ID (if special file) */
    off_t     st_size;        /* total size, in bytes */
    blksize_t st_blksize;     /* blocksize for filesystem I/O */
    blkcnt_t  st_blocks;      /* number of 512B blocks allocated */

    /* Since Linux 2.6, the kernel supports nanosecond
     *                   precision for the following timestamp fields.
     *                                     For the details before Linux 2.6, see NOTES. */

    struct timespec st_atim;  /* time of last access */
    struct timespec st_mtim;  /* time of last modification */
    struct timespec st_ctim;  /* time of last status change */

#define st_atime st_atim.tv_sec      /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};

#endif

//查看文件信息命令
//deng@itcast:~/share/4th$ stat txt

//获取文件相关信息
int main(void)
{
    int ret = -1;

    struct stat buf;

    memset(&buf, 0, sizeof(buf));
    //获取文件相关信息
    ret = stat("txt", &buf);
    if (-1 == ret)
    {
        perror("stat"); 
        return 1;
    }

    printf("st_dev: %lu\n", buf.st_dev);
    printf("st_ino: %lu\n", buf.st_ino);
    printf("st_nlink: %lu\n", buf.st_nlink);
    printf("st_uid: %d\n", buf.st_uid);
    printf("st_gid: %d\n", buf.st_gid);
    printf("st_rdev:%lu\n", buf.st_rdev);
    printf("st_size: %ld\n", buf.st_size);
    printf("st_blksize: %ld\n", buf.st_blksize);
    printf("st_blocks: %ld\n", buf.st_blocks);


    return 0;
}

stat1.c

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

#if 0
struct stat {
    dev_t     st_dev;         /* ID of device containing file */
    ino_t     st_ino;         /* inode number */
    mode_t    st_mode;        /* protection */
    nlink_t   st_nlink;       /* number of hard links */
    uid_t     st_uid;         /* user ID of owner */
    gid_t     st_gid;         /* group ID of owner */
    dev_t     st_rdev;        /* device ID (if special file) */
    off_t     st_size;        /* total size, in bytes */
    blksize_t st_blksize;     /* blocksize for filesystem I/O */
    blkcnt_t  st_blocks;      /* number of 512B blocks allocated */

    /* Since Linux 2.6, the kernel supports nanosecond
     *                   precision for the following timestamp fields.
     *                                     For the details before Linux 2.6, see NOTES. */

    struct timespec st_atim;  /* time of last access */
    struct timespec st_mtim;  /* time of last modification */
    struct timespec st_ctim;  /* time of last status change */

#define st_atime st_atim.tv_sec      /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};

S_IFMT     0170000   bit mask for the file type bit field

S_IFSOCK   0140000   socket
S_IFLNK    0120000   symbolic link
S_IFREG    0100000   regular file
S_IFBLK    0060000   block device
S_IFDIR    0040000   directory
S_IFCHR    0020000   character device
S_IFIFO    0010000   FIFO


#endif

//查看文件信息命令
//deng@itcast:~/share/4th$ stat txt

//获取文件相关信息
int main(int argc, char **argv)
{
    int ret = -1;

    struct stat buf;

    if (2 != argc)
    {
        printf("usage: ./a.out filename\n"); 
        return 1;
    }

    memset(&buf, 0, sizeof(buf));
    //获取文件相关信息
    ret = stat(argv[1], &buf);
    if (-1 == ret)
    {
        perror("stat"); 
        return 1;
    }

    printf("st_dev: %lu\n", buf.st_dev);
    printf("st_ino: %lu\n", buf.st_ino);
    printf("st_nlink: %lu\n", buf.st_nlink);
    printf("st_uid: %d\n", buf.st_uid);
    printf("st_gid: %d\n", buf.st_gid);
    printf("st_rdev:%lu\n", buf.st_rdev);
    printf("st_size: %ld\n", buf.st_size);
    printf("st_blksize: %ld\n", buf.st_blksize);
    printf("st_blocks: %ld\n", buf.st_blocks);

#if 0
    switch((buf.st_mode & S_IFMT))
    {
        case S_IFSOCK:   
            printf("socket\n");
            break;
        case S_IFLNK :   
            printf("symbolic link\n");
            break;
        case S_IFREG :   
            printf("regular file\n");
            break;
        case S_IFBLK :   
            printf("block device\n");
            break;
        case S_IFDIR :   
            printf("directory\n");
            break;
        case S_IFCHR :   
            printf("character device\n");
            break;
        case S_IFIFO :   
            printf("FIFO\n");
            break;
        defalt:
            printf("未知类型....\n");
    }
#else

    if (S_ISREG(buf.st_mode) ) 
        printf("is it a regular file \n"); 
    if (S_ISDIR(buf.st_mode) ) 
        printf("directory            \n");   
    if (S_ISCHR(buf.st_mode) ) 
        printf("character device     \n");   
    if (S_ISBLK(buf.st_mode) ) 
        printf("block device         \n"); 
    if (S_ISFIFO(buf.st_mode)) 
        printf("FIFO (named pipe)    \n");   
    if (S_ISLNK(buf.st_mode) ) 
        printf("symbolic link        \n");    
    if (S_ISSOCK(buf.st_mode)) 
        printf("socket               \n");   


#endif

    //判断文件所属者权限
    if (buf.st_mode & S_IRUSR)
        printf("r");
    else
        printf("-");

    buf.st_mode & S_IWUSR ? printf("w") : printf("-");
    buf.st_mode & S_IXUSR ? printf("x") : printf("-");

    //判断文件所属组权限
    buf.st_mode & S_IRGRP ? printf("r") : printf("-");
    buf.st_mode & S_IWGRP ? printf("w") : printf("-");
    buf.st_mode & S_IXGRP ? printf("x") : printf("-");

    //判断文件其它权限
    buf.st_mode & S_IROTH ? printf("r") : printf("-");
    buf.st_mode & S_IWOTH ? printf("w") : printf("-");
    buf.st_mode & S_IXOTH ? printf("x") : printf("-");



    printf("\n");





    return 0;
}

access.c

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (2 != argc)
    {
        printf("usage: ./a.out filename\n"); 
        return 1;
    }

    for (int i = 0; i < argc; i++)
    {
        printf("argv[%d]: %s\n", i, argv[i]); 
    }

    //判断文件是否存在
    if (access(argv[1], F_OK) == 0)
    {
        printf("文件存在...\n"); 
    }
    else
    {
        printf("文件不存在....\n"); 
    }

    //判断文件是否有读的权限
    if (access(argv[1], R_OK) == 0)
    {
        printf("可以读\n"); 
    }
    else
    {
        printf("不可以读\n"); 
    }

    return 0;
}

symlinc.c

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (3 != argc)
    {
        printf("usage: ./a.out filename1 filename2\n"); 
        return 1;
    }

    //创建一个符号链接
    if (-1 == symlink(argv[1], argv[2]))
    {
        perror("symlink"); 
        return 1;
    }


    return 0;
}

dup.c

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

//文件描述符复制
int main(void)
{
    int fd = -1;
    int newfd = -1;

    //1. 打开文件
    fd = open("txt", O_RDWR | O_CREAT, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }

    //2. 复制文件描述符
    //newfd = dup(fd);
    newfd = 10;
    //如果newfd文件描述符已经与其它文件关联, 那么先close, 然后在使用该数字
    newfd = dup2(fd, newfd);
    if (-1 == newfd)
    {
        perror("dup"); 
        return 1;
    }

    printf("fd : %d  newfd: %d\n", fd, newfd);
    
    //3. 关闭文件
    close(fd);
    close(newfd);

    return 0;
}

dup2.c

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

//文件描述符复制
int main(void)
{
    int fd = -1;
    int newfd = -1;

    //1. 打开文件 Ctrl + P
    fd = open("txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }

    //2. 复制文件描述符
    //newfd = dup(fd);
    newfd = 10;
    //如果newfd文件描述符已经与其它文件关联, 那么先close, 然后在使用该数字
    newfd = dup2(fd, newfd);
    if (-1 == newfd)
    {
        perror("dup"); 
        return 1;
    }

    printf("fd : %d  newfd: %d\n", fd, newfd);

    write(fd, "123456789", 9);
    write(newfd, "ABCDEFGHI", 9);

    
    //3. 关闭文件
    close(fd);
    close(newfd);

    return 0;
}

fcntl.c

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

//文件描述符复制
int main(void)
{
    int fd = -1;
    int newfd = -1;

    //1. 打开文件 Ctrl + P
    fd = open("txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }

    //2. 复制文件描述符 寻找一个大于或者等于10的最小的可以用文件描述符返回
    newfd = fcntl(fd, F_DUPFD, 10);
    if (-1 == newfd)
    {
        perror("fcntl"); 
        return 1;
    }
    printf("fd : %d  newfd: %d\n", fd, newfd);

    write(fd, "123456789", 9);
    write(newfd, "ABCDEFGHI", 9);

    
    //3. 关闭文件
    close(fd);
    close(newfd);

    return 0;
}

 fcntl.c

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

//文件描述符复制
int main(void)
{
    int fd = -1;
    int ret = -1;

    //1. 打开文件 Ctrl + P
    fd = open("txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (-1 == fd)
    {
        perror("open"); 
        return 1;
    }


    //2. 获取文件状态标志
    ret = fcntl(fd, F_GETFL);
    if (-1 == ret)
    {
        perror("fcntl"); 
        return 1;
    }

    if (ret & O_NONBLOCK)
    {
        printf("设置为非阻塞...\n"); 
    }
    else
    {
        printf("设置为阻塞...\n"); 
    }


    //设置为非阻塞
    ret |= O_NONBLOCK;
    ret = fcntl(fd, F_SETFL, ret);
    if (-1 == ret)
    {
        perror("fcntl"); 
        return 1;
    }

    //2. 获取文件状态标志
    ret = fcntl(fd, F_GETFL);
    if (-1 == ret)
    {
        perror("fcntl"); 
        return 1;
    }

    if (ret & O_NONBLOCK)
    {
        printf("设置为非阻塞...\n"); 
    }
    else
    {
        printf("设置为阻塞...\n"); 
    }



        
    //3. 关闭文件
    close(fd);

    return 0;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37274076/article/details/123313491

linux文件想关接口______123的博客-爱代码爱编程

3.1 dup函数 #include <unistd.h> int dup(int oldfd); 功能: 通过 oldfd 复制出一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描

linux 如何开放端口和关闭端口_创客公元的博客-爱代码爱编程_linux系统怎么开端口

一、查看哪些端口被打开 netstat -anp 二、关闭端口号: iptables -A OUTPUT -p tcp --dport 端口号-j DROP 三、打开端口号: iptables -A INPUT -p

小练习----春夏秋冬,回文数,不死神兔,去掉最高最低求和,数组反转,简单加密,switch语句-爱代码爱编程

春夏秋冬 Scanner sc = new Scanner(System.in); int a = sc.nextInt(); if (a == 1 || a == 2 || a == 12) { System.out.

【算法】罗马数字转数字_dustdawn的博客-爱代码爱编程

/** * 罗马数字转数字 * @author DUSTDAWN * 字符 数值 I 1 V 5 X 10 L

第二十六节 linux系统编程管理文件和目录-基本概念(一)_嵌入式开发学习者的博客-爱代码爱编程

-------------------------------------资源来源于网络,仅供自学使用,如有侵权,联系我必删. 基本概念 1)• linux中一切皆文件! – 目录、软链接、硬链接以及前面介绍的普通文件、设备节点等,都可以理解为文件 – 目录管理和普通文件稍微有点不同,不过具有高度的相似 • 从这期视频开始会更加频繁的使用man命令去学

Java程序设计——判断数字是否为回文数-爱代码爱编程

编写一个Java应用程序,用户从键盘输入一个1~99999之间的整数,程序将判断这个数是几位数,并判断这个数是否为回文数。 思路与步骤 (1)所谓“回文数”,是设n是任意自然数。若将n的各位数字反向排列所得自然数n1与n相等,则称n 为一回文数。例如,若 n=1234321,则n 为回文数;但若n =1234567,则 n不是回文数。 (2)需要判断键

判断一个数是否为回文数(三种方法,详细注解)-爱代码爱编程

题目要求: 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。  回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。 解法一: 先将 整数转为字符串 ,然后将字符串逆转后判断与原字符串是否相等。代码如下: public static boolean isP