zoukankan      html  css  js  c++  java
  • 《Linux/Unix系统编程手册》读书笔记1

    《Linux/Unix系统编程手册》读书笔记 目录

    最近这一个月在看《Linux/Unix系统编程手册》,在学习关于Linux的系统编程。之前学习Linux的时候就打算写关于Linux的学习记录,因为觉得自己学得不好,老是写不出东西。但是现在觉得学习记录应该坚持写,慢慢就会有收获,坚持写才可以锻炼自己的表达能力。

    《Linux/Unix系统编程手册》这本书的评价很高,但是个人觉得翻译得不太好。其实终究是因为自己的英文阅读能力太差和没什么钱,只能看翻译版。看了接近一个月,觉得这本书介绍的接口很详细,程序清单基本会提及到介绍的接口。个人觉得作为入门书应该是可以的,起码看完一遍会有初步的认识,而且作为参考手册也不错。打算看完这本书之后,继续学习《UNIX环境高级编程》,学无止境。

    第1章:

    介绍了一些历史,关于Linux、Unix和C;还有一些标准POSIXSUS 

    第2章:

    介绍Linux和Unix的一些基本概念。

    1.操作系统的两个含义:一,包含管理和分配计算机资源的核心层软件和附带的所有标准软件;二,仅仅指管理和分配计算机资源的核心层软件。

    2.内核的作用:进程调度、内存管理、文件系统、创建和终止进程、对设备的访问、联网、提供API。其实就是抽象,用户通过内核来使用硬件,而不用直接与硬件打交道。

    3.用户态和内核态。

    。。。。。。。。。。。。。。。。还有一堆的概念。。。。。。。。。。。。。。。。。。。

    第3章

    介绍系统编程的概念。

    系统调用(systerm calls)是用户程序与操作系统之间的接口,系统调用在内核态。库函数(library functions),一些库函数是通过系统调用来实现,好处是提供了比底层系统调用更方便的接口。

    还有本书的代码所需的一些函数、头文件。。。。。。。。。。。

    见链接:http://www.man7.org/tlpi/

    第4章

    介绍了文件I/O。

    文件描述符,用来表示已经打开的文件(所有类型),是一非负整数。最基本的文件描述符0(标准输入)、1(标准输出)、2(标准错误)。

    I/O操作:首先通过调用open获取一个文件描述符,再对该文件描述符进行read或者write操作,最后使用close释放文件描述符和相关资源。

    open()调用,打开一个文件或者创建一个文件。

    1 #include <sys/stat.h>
    2 #include <fcntl.h>
    3 
    4 int open(const char *pathname, int flags, .../* mode_t mode */);

    成功调用返回文件描述符,失败返回-1;

    1、pathname为打开文件的文件名; flags为位掩码,用于指定文件的访问模式;mode为位掩码参数,用于指定文件的访问权限(可选)。

    2、flags位掩码的标志分为文件访问模式标志、文件创建标志、已打开文件的状态标志;其中文件访问模式标志如下表,这些标志不能同时使用。

    访问模式 描述
     O_RDONLY 以只读方式打开文件 
    O_WRONLY 以只写方式打开文件
    O_RDWR 以读写方式打开文件

    比较常用的标志还有O_APPEND(总是在文件尾部添加数据)、O_CREAT(如果要打开的文件不存在就新建一个空文件)、O_EXCL(与O_CREAT结合使用表明如果文件已经存在,就不会打开文件)。

    3、open()函数的错误:省略。

    read()调用,从文件描述符对应的文件中读取数据。

    #include <unistd.h>
    
    ssize_t read(int fd, void *buffer, size_t count);

    fd为文件描述符;buffer为存储数据的缓冲区;count为最多能读取的字节数。

    成功调用返回实际读取字节数,遇到文件结束符返回0,出现错误返回-1。

    PS:要在缓冲区最后添加一个表示终止的空字符。

    write()调用,往文件描述符对应的文件写入数据。

    1 #include <unistd.h>
    2 
    3 ssize_t write(int fd, void *buffer, size_t count);

    fd为文件描述符;buffer为存储数据的缓冲区;count为准备从buffer写入到文件的数据的字节数。

    成功调用返回实际写入文件的字节数, 失败返回-1。

    close()调用,关闭已经打开的文件描述符。

    1 #include <unistd.h>
    2 
    3 int close(int fd);

    fd为文件描述符。

    成功调用返回0,失败返回-1 。

    所有类型的文件和设备驱动都实现了相同的I/O接口,所以无需针对特殊的文件编写代码。

    文件偏移量:读写偏移量或指针,是执行下一个read和write操作的文件起始位置(相对与文件头部起始点)。

    lseek(),改变文件偏移量。

    1 #include <unistd.h>
    2 
    3 off_t lseek(int fd, off_t offset, int whence);

    fd为文件描述符,offset为偏移量(字节),whence为表明解释offset参数的方法。

    whence参数:

    SEEK_SET 将文件偏移量设置为从文件头起始点开始的offset个字节
    SEEK_CUR 相对于当前文件偏移量,再加上offset个字节
    SEEK_END 将文件偏移量设置为起始于文件尾部的offset个字节

    文件空洞 :当文件的偏移量大于文件的当前长度时,文件结尾到新写入数据之间的空间称为文件空洞。读取文件空洞的内容会返回以0填充的缓冲区。

         “空洞是否占用磁盘空间由文件系统决定”----《百度百科》

         “如果空洞的边界落在块内,而非恰好落在块的边界上,则会分配一个完整的块来存储数据,块中与空洞相关的部分则以空字节填充”----书本提示

         

    练习:

    4-1:tee命令是从标准输入中读取数据,直至文件结尾,随后将数据写入标准输入和命令行参数所指定的文件。请使用I/O系统调用实现tee命令,默认情况下,若已存在命令行参数指定文件同名的文件tee命令会将其覆盖。如文件以存在,请实现-a命令行选项(tee -a file)在文件结尾出追加数据。

     1 /*
     2  * =====================================================================================
     3  *
     4  *       Filename:  my_tee.c
     5  *
     6  *    Description:  tee
     7  *
     8  *        Version:  1.0
     9  *        Created:  2014年03月14日 18时23分04秒
    10  *       Revision:  none
    11  *       Compiler:  gcc
    12  *
    13  *         Author:  alan (), alan19920626@gmail.com
    14  *   Organization:如果输入为my_tee -a会出现错误而不是程序自动停止而且报错!!!!需要改进!!!
    15  *
    16  * =====================================================================================
    17  */
    18 
    19 #include <sys/stat.h>
    20 #include <fcntl.h>
    21 #include <ctype.h>
    22 #include "tlpi_hdr.h"
    23 
    24 #define MAX_READ 20
    25 
    26 int main(int argc, char *argv[]){
    27     int fd, opt;
    28     char buf[MAX_READ + 1];
    29     ssize_t numRead; 
    30     off_t offset;
    31 
    32     if(argc < 2 || strcmp(argv[1], "--help") == 0)
    33         usageErr("%s [-a] file");
    34 
    35     fd = open(argv[argc-1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    36     if(fd == -1)
    37         errExit("open");
    38 
    39     offset = lseek(fd, 0, SEEK_SET);
    40     while((opt = getopt(argc, argv, ":a")) != -1){
    41         switch(opt){
    42             case 'a':
    43                 //file = optarg;
    44                 offset = lseek(fd, -1, SEEK_END);
    45                 break;
    46             case '?':
    47             default:
    48                 fprintf(stderr, "%s option: '-%c' is invalid: ignore
    ", argv[0], optopt);
    49                 exit(EXIT_FAILURE);
    50                 break;
    51         }
    52     }
    53 
    54 
    55     while((numRead = read(STDIN_FILENO, buf, MAX_READ)) > 0){
    56         buf[numRead] = '';
    57         
    58         if(write(STDOUT_FILENO, buf, numRead+1) != (numRead+1))
    59             fatal("couldn't write whole buf");
    60         if(write(fd, buf, numRead) != (numRead))
    61             fatal("couldn't write whole buf");
    62     }
    63 
    64     if(numRead == -1)
    65         errExit("read");
    66 
    67     if(close(fd) == -1)
    68         errExit("close file");
    69 
    70     exit(EXIT_SUCCESS);
    71 }

    测试:

    lancelot@debian:~/Code/tlpi$ cat > t1
    This is the first line.
    lancelot@debian:~/Code/tlpi$ cat t1
    This is the first line.
    lancelot@debian:~/Code/tlpi$ ./my_tee t1
    This is the second line.
    This is the second line.
    This is the third line.
    This is the third line.
    
    
    lancelot@debian:~/Code/tlpi$ cat t1
    This is the second line.
    This is the third line.
    
    lancelot@debian:~/Code/tlpi$ ./my_tee -a t1
    This is the append line.
    This is the append line.
    lancelot@debian:~/Code/tlpi$ cat t1
    This is the second line.
    This is the third line.
    This is the append line.

    4-2:编写一个类似cp命令的程序,当使用该程序复制一个包含空洞(连续的空字节)的普通文件时,要求目标文件的空的与源文件保持一致。

     1 /*
     2  * =====================================================================================
     3  *
     4  *       Filename:  my_cp.c
     5  *
     6  *    Description:  
     7  *
     8  *        Version:  1.0
     9  *        Created:  2014年04月03日 17时02分43秒
    10  *       Revision:  none
    11  *       Compiler:  gcc
    12  *
    13  *         Author:  alan (), alan19920626@gmail.com
    14  *   Organization:  
    15  *
    16  * =====================================================================================
    17  */
    18 
    19 #include <sys/stat.h>
    20 #include <fcntl.h>
    21 #include <ctype.h>
    22 #include "tlpi_hdr.h"
    23 
    24 #define BUF_SIZE 1024
    25 
    26 int main(int argc, char *argv[]){
    27     int inputFd, outputFd, openFlags;
    28     mode_t filePerms;
    29     ssize_t numRead;
    30     char buf[BUF_SIZE];
    31 
    32     if(argc != 3 || strcmp(argv[1], "--help") == 0)
    33         usageErr("%s old-file new-file
    ", argv[0]);
    34 
    35     inputFd = open(argv[1], O_RDONLY);
    36     if(inputFd == -1)
    37         errExit("open file %s", argv[1]);
    38 
    39     openFlags = O_CREAT | O_WRONLY | O_TRUNC;
    40     filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
    41     outputFd = open(argv[2], openFlags, filePerms);
    42     if(outputFd == -1)
    43         errExit("open file %s", argv[2]);
    44 
    45     while((numRead = read(inputFd, buf, BUF_SIZE)) > 0)
    46         if(write(outputFd, buf, numRead) != numRead)
    47             fatal("couldn't write whole buffer");
    48     if(numRead == -1)
    49         errExit("read");
    50     if(close(inputFd) == -1)
    51         errExit("close input");
    52     if(close(outputFd) == -1)
    53         errExit("close output");
    54 
    55     exit(EXIT_SUCCESS);
    56 }

    测试:首先通过书本的程序清单提供的seek_io.c来使t2出现空洞。

    lancelot@debian:~/Code/tlpi$ cat t2
    This is the first line.
    This is the second line.
    This is the third line.
    lancelot@debian:~/Code/tlpi$ gcc -o seek_io seek_io.c error_functions.c get_num.c
    lancelot@debian:~/Code/tlpi$ ./seek_io t2 s100000 wabc
    s100000: seek succeeded
    wabc: wrote 3 bytes
    lancelot@debian:~/Code/tlpi$ cat t2
    This is the first line.
    This is the second line.
    This is the third line.
    abclancelot@debian:~/Code/tlp./seek_io t2 s50000 R5
    s50000: seek succeeded
    R5: 00 00 00 00 00 

    可以看到文件偏移量为50000的内容为空字节。。。。。

    然后进行复制。

    lancelot@debian:~/Code/tlpi$ ./my_cp t2 t3
    lancelot@debian:~/Code/tlpi$ ls -l t2 t3
    -rw-r--r-- 1 lancelot lancelot 100003  4月  3 17:27 t2
    -rw-r--r-- 1 lancelot lancelot 100003  4月  3 17:34 t3
    lancelot@debian:~/Code/tlpi$ ./seek_io t3 s50000 R5
    s50000: seek succeeded
    R5: 00 00 00 00 00 

    可以看到两个文件的大小相同,而且从t3文件偏移量为50000开始读取5个字节都为空字节。

  • 相关阅读:
    CentOS6.5 安装 tomcat
    CentOS6.5 安装 jdk1.7
    CentOS6.5 mysql 5.5安装
    java使用split切割字符串的时候,注意转义字符
    hibernate中设置BigDeCimal的精度
    powerdesinger中建立一个表后,出现Existence of index的警告
    MySQL数据库一个字段对应多个值得模糊查询
    系统收到了多个不同的 Content-Disposition 标头。为了避免遭到 HTTP 响应拆分攻击,这种情况是不允许的。
    下载的文件名字当前时间(精确到秒)+ 随机数
    简单的poi导出excel文件
  • 原文地址:https://www.cnblogs.com/alan-forever/p/3643411.html
Copyright © 2011-2022 走看看