Posts LInux系统编程01_IO
Post
Cancel

LInux系统编程01_IO

1. open

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 *      x   ---  1
 *      w  ---  2
 *      r  ----  4 
 */

 int main(){
     int fd = 0;
     // 只写
     fd = open("temp.txt",O_WRONLY);
    // 追加写
    fd = open("temp2.txt",O_WRONLY|O_APPEND);
    // 只读的方式打开 若不存在 就以权限777创建
    // 其实这里是有点小bug的, 0777  要与 umask 相与    详见p48
    fd = open("temp3.txt",O_RDONLY|O_CREAT,0777);
 }

**

错误信息

这个在之前看unix系统编程实践中总是蒙圈

1
2
3
4
5
6
7
8
9
10
11

 int main(){
     int fd = 0;
     fd = open("temp.txt",O_RDONLY);
     // 把errno看为一个操作系统的全局变量即可啦
    printf("%d\n",errno);     
    printf("------------------------\n");
    printf("%s\n",strerror(errno));
    return 0;
 }

2. read

函数原型: ssize_t read(int fd, void *buf, size_t count);

  1. ssize_t : 有符号的返回数
  2. 读到 0 时到结尾
  3. count 缓冲区大小

3. write

函数原型 : ssize_t write(int fd, const void *buf, size_t count);

  1. const 问题 缓冲区不可变
  2. count 是实际数据大小 , 跟缓冲区大小无关

返回值暂略, 主要看man 2 page

实现cp命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<unistd.h>
#include<sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include<string.h>

int main(int argc,char *argv[]){
    char buf[1024];
    int  n = 0;
    int fd1 = open(argv[1],O_RDONLY);  // 只读
    int fd2 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0644);  // 读权限肯定有  如果没有就创建  如果有这个文件 trunc 重写为0

    while ((n = read(fd1,buf,1024)) != 0)
    {
        
        write(fd2,buf,n);
    }

    close(fd1);
    close(fd2);
    

    return 0;
    
}

perror 问题

  1. perror(“open argv1 error”); // perror 会根据全局的errno 自动生成错误提示信息 贼方便
  2. 错误信息: open argv1 error: No such file or directory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int main(int argc,char *argv[]){
    char buf[1024];
    int  n = 0;
    int fd1 = open(argv[1],O_RDONLY);  // 只读
    if  ( fd1 == -1){
        perror("open argv1 error");   // perror 会根据全局的errno 自动生成错误提示信息 贼方便
        exit(1);
    }
    int fd2 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0644);  // 读权限肯定有  如果没有就创建  如果有这个文件 trunc 重写为0
    if  ( fd2== -1){
        perror("open argv2 error");
        exit(1);
    }
    while ((n = read(fd1,buf,1024)) != 0)
    {
        if (n < 0)
        {
            /* code */
            perror(" read error");
            break;
        }
        
        write(fd2,buf,n);
    }

    close(fd1);
    close(fd2);
    

    return 0;
    
}

4. 系统调用与库函数 详解缓冲区问题

  1. 是不是系统调用一定比缓冲区要快?

    不是,在有现成的库函数时,尽量使用库函数。 fget() 与 fput() 对比 write() read()

在fput() 与 write() 都使用1字节的buf情况下,fupt() 比write() 要快一个数量级,fput有一个用户级缓存,详情见p53

5. fcontl

改变文件状态 比如阻塞与非阻塞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(){
    int flag = 0;
    flag = fcntl(STDIN_FILENO,F_GETFD);
    if (flag == -1)
    {
        perror("fcntl error");
        exit(1);
    }
    // printf("%d",flag);   // 0


    flag  |= O_NONBLOCK;  // 调为非阻塞状态  位或
    int ret = fcntl(STDIN_FILENO,F_SETFD,flag);  // F_SETFD

    return 0;
}

6. lseek()

  1. 应用场景

    • 文件的读与写 使用的是同一个偏移位置

    • 使用lseek获取,拓展文件大小。

    • 扩展文件大小

  2. 返回值

    较起始位置的偏移量

  3. 函数原型

.int lseek(int fd, off_t offset, int whence);

 SEEK_SET:偏移到文件头+ 设置的偏移量   SEEK_CUR:偏移到当前位置+设置的偏移量   SEEK_END:偏移到文件尾置+设置的偏移量

  1. 代码举例

函数思想其实还是很简单,起始位置由后两个参数决定

1
2
3
4
5
6
int main(){
    int fd,ret;
    fd = open("03_cp.c",O_RDONLY);
    ret = lseek(fd,0,SEEK_END);
    printf("%d",ret);
}

7. 传入参数与传入参数

This post is licensed under CC BY 4.0 by the author.

Contents

Trending Tags