Linux 高级编程之小结(一)

来源:互联网 发布:望京李春姬直播软件 编辑:程序博客网 时间:2024/05/22 17:06

 新人小白,个人总结,谨慎参考。嗯嗯...

一、    基本I/O调用

1.    I/O库函数

#include<stdlib.h>

#include<stdio.h>

1)   fopen     --打开文件

FILE *fopen(const char*path, const char *mode);

     path:要打开的文件的路径。

     mode:打开文件的方式。

         r 以只读方式打开文件,该文件必须存在。

r+ 以可读写方式打开文件,该文件必须存在。

rb+ 读写打开一个二进制文件,允许读写数据,文件必须存在。

w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。

w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)

a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。(原来的EOF符不保留)

wb 只写打开或新建一个二进制文件;只允许写数据。

wb+ 读写打开或建立一个二进制文件,允许读和写。

ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。

wx 创建文本文件,只允许写入数据。

wbx 创建一个二进制文件,只允许写入数据。

w+x 创建一个文本文件,允许读写。

wb+x 创建一个二进制文件,允许读写。

返回值:若打开成功,返回一个指向文件的指针;失败返回NULL。

2)   fclose     --关闭文件,释放相关缓冲区及文件指针

int fclose(FILE *fp);

     fp:指向要关闭文件的文件指针。

返回值:若关闭成功,返回0;失败返回1,并且返回error。

3)   fgets      --读取文本中的信息

char *fgets(char *s, int size, FILE *stream);

     s:读取缓冲区的首地址。

     size:缓冲区的大小。

     stream:要读取的文件指针。

函数功能:从stream指向的文件中读取size-1大小的字符放入s指向的缓冲区。如果过程中遇到换行,结束读取。

返回值:成功返回s指向的地址。

4)   fputs      --向文件写入内容

int fputs(const char*s, FILE *stream);

     s:要写入文件的缓冲区首地址。

     stream:要写入文件的文件指针。

返回值:成功返回0;失败返回EOF。

5)   fread      --从文件流中读取数据

size_t fread(void *ptr,size_t size, size_t nmemb, FILE *stream);

     ptr:用于读取的缓冲区首地址。

     size:要读取的每个数据的字节数。

     nmemb:要读取的数据个数。

     stream:文件指针。

返回值:实际读取的元素个数。

6)   fwrite     --向文件写入数据

size_t fwrite(constvoid *ptr, size_t size, size_t nmemb,FILE *stream);

ptr:要写的缓冲区的首地址。

Size:要写入的内容的每个的字节数。

Nmemb:要写入的数据的个数,每个size字节。

Stream:只想要写入文件的指针。

返回值:实际写入的数据的个数,每个size字节。

7)   feof        --检查文件中的文件结束符

int feof(FILE *stream);

返回值:若文件结束,返回0.

2.    系统调用

#include<unistd.h>

#include<fcntl.h>

1)   open      --打开亦可创建文件

int open(const char *pathname, int flags, mode_t mode);

pathname:文件路径。

flags:宏定义,适应于不同的文件打开情况。

O_RDONLY只读模式

O_WRONLY只写模式

O_RDWR读写模式

O_APPEND每次写操作都写入文件的末尾

O_CREAT如果指定文件不存在,则创建这个文件

O_EXCL如果要创建的文件已存在,则返回-1,并且修改errno的值

O_TRUNC如果文件存在,并且以只写/读写方式打开,则清空文件全部内容(即将其长度截短为0)

O_NOCTTY如果路径名指向终端设备,不要把这个设备用作控制终端。

O_NONBLOCK如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O

              mode:指定打开文件后的权限。是否需要根据flags不同而不同。

              返回值:成功返回文件描述符。

2)   write      --向文件写入数据

ssize_t write(int fd, const void *buf,size_t count);

     fd:文件描述符。 

buf:要写入文件的数据缓冲区首地址。

count:要写入文件的数据字节个数。

返回值:若成功,返回实际写入字节数。失败返回-1,并且储存错误代码。

3)   read       --从文件中读取数据

ssize_t read(int fd,void *buf, size_t count);

     fd:文件描述符。

     Buf:读取文件缓冲区首地址。

     Count:读取字节个数。

     返回值:若成功,返回实际读取数据字节个数。若失败,返回-1,并且设置错误代码。

4)   lseek      --设置当前文件的偏移量

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

     fd:文件描述符。

     offset:根据参数whence来移动读写位置的位移数

     whence:可以是以下任意一个

       SEEK_SET 将读写位置指向文件头后再增加offset个位移量。

SEEK_CUR 以目前的读写位置往后增加offset个位移量。

SEEK_END 将读写位置指向文件尾后再增加offset个位移量。

当whence 值为SEEK_CUR 或SEEK_END时,参数offet允许负值的出现。

5)   dup/dup2   --重定向

int dup(int oldfd);

     本函数会自己寻找最小的文件描述符进行重定向。

     oldfd:要重定向的文件描述符。

     返回值:若成功,返回新的文件描述符。若失败,返回-1。

int dup2(int oldfd, intnewfd);

     本函数可以指定新的文件描述符,如果newfd已经打开,则先关闭。若oldfd == newfd,则返回newfd,且不关闭。

     oldfd:要重定向的文件描述符。

newfd:新的文件描述符。

返回值:若成功,返回新的文件描述符。若失败,返回-1。

二、    EXT2文件系统

1.    创建一个文件,模拟文件系统操作:

dd if=/dev/zeroof=fs.bin count=256 bs=4k  

---将输入文件写入到制定大小的输出文件

mke2fs fs.bin   

---格式化成ext2文件系统

mke2fs /dev/da   

---格式化硬盘

2.    EXT2文件系统的总体储存布局

3.    文件系统相关操作函数

#include <sys/types.h>

#include <dirent.h>

1)   opendir      --打开目录

DIR *opendir(const char*name);

     name:要打开的目录的路径。

     返回值:若成功,返回DIR类型的指针。若失败,返回NULL。

2)   readdir       --读取目录

struct dirent*readdir(DIR *dirp);

返回值:成功则返回参数dirp目录流的下个目录进入点。失败或者读到目录结尾,则返回NULL。

结构dirent定义如下:
struct dirent
{
ino_t d_ino;
ff_t d_off;
signed short int d_reclen;
unsigned char d_type;
har d_name[256];
};
d_ino 此目录进入点的inode
d_off 目录文件开头至此目录进入点的位移
d_reclen _name的长度,不包含NULL字符
d_type d_name 所指的文件类型
d_name 文件名

3)   closedir      ---关闭一个目录,必须与opendir匹配出现

int closedir(DIR*dirp);

返回值:若成功,返回0;若失败,返回-1,并且储存错误参数。

4)   mkdir     --创建新目录

int mkdir(const char*pathname, mode_t mode);

     pathname:目录创建的路径。

     mode:新目录的权限。

         可取值:可取情况很多,略。

返回值:若成功,返回0;若失败,返回-1,并且储存错误参数。

5)   rmdir     --删除一个空目录,使用时目录必须为空。

int rmdir(const char *pathname);

     pathname:目录创建的路径。

返回值:若成功,返回0;若失败,返回-1,并且储存错误参数。

三、    进程

1.    进程地址空间

2.    进程控制

1)   fork函数

#include <unistd.h>

pid_t fork(void);

     函数作用:在主进程下创建一个子进程,当下进程为此子进程的父进程。所谓创建,也就是进程拷贝。对于fock函数,拷贝时会将BUFF中的缓存同样拷贝一份,进程控制块也会拷贝一份。有一部分不会拷贝,比如:只读文本段。由于只读不写的文本段,两个进程公用,且互相不知道。

     返回值:子进程的为0,父进程为正整数。

2)   vfock函数

pid_t vfork(void);

     函数作用:和fork的拷贝方式不一样,仅拷贝PCB,一定是子进程先执行。当且仅当子进程退出或者调用exce后,父进程才可以运行。

3)   getpid函数

pid_t getpid(void);

函数作用:得到本进程进程号。

返回值:进程号。

4)   getppid函数

pid_t getppid(void);

函数作用:得到父进程进程号。

返回值:进程号。

5)   exec函数

int execl(const char*path, const char *arg, ...);

int execlp(const char*file, const char *arg, ...);

int execle(const char *path, constchar *arg,...,char * const envp[]);

int execv(const char *path, char*const argv[]);

int execvp(const char*file, char *const argv[]);

int execvpe(const char*file, char *const argv[],

                   char *const envp[]);

     函数作用:在进程需要执行不同的代码分支,子进程往往要调用一种exec函数以执行另一个程序。该进程用户空间代码完全被新程序替换。从而进行新的程序的执行 。本函数不创建新的进程,只是霸占现在的进程的空间。

3.    进程间交互

              由此可见,进程无法直接进行信息交互。进程间的交互必须进过内核,所以产生如下方法:

1)   管道

int pipe(int pipefd[2]);

     通过此函数,进程知道了内核中一个管道的文件描述符。fds[0]--读端  与fds[1]--写端。可通过文件描述符进行管道的读写。

     然后进行进程的创建,通过fork函数,产生子进程。由于管道存在与内核,所以不被拷贝。此时,对于父进程及子进程都知道了管道的文件描述符fd。相应关闭某一支,即可进行父进程与子进程间的通信。如图:

     但是,管道尽可以进行单向通信,因此如果使用管道使进程间进行双向通信时,必须建立两个管道。

2)   有名管道

FIFO:是一种特殊类型的文件。程序不能以O_RDWR模式打开FIFO文件进行读写操作,这样做的后果并未明确定义, 如果一个管道以读/写方式打开, 进程就会从这个管道读回它自己的输出.

如果需要在程序之间双向传递数据,最好是使用一对FIFO或管道,一个方向使用一个;或者(但不常用),采用先关闭再重新打开FIFO的方法来明确改变数据流的方向.

3)   共享内存

共享内存允许两个或多个进程共享一块内存,这块内存映射到各个进程自己独立的地址空间(就是那个假的,进程得儿呵呵的还不知道的地址空间。),从而使得这些进程可以相互通信。

A.   共享内存使用的函数

#include <sys/types.h>

#include <sys/shm.h>

                                           i.         int shmget(key_t key, size_t size, int shmflg);     --创建共享内存

key:唯一的key可以给共享内存段命名。

size:共享内存容量的字节数。

shmflg:创建时的权限标志,类比于文件创建。

返回值:成功则返回一个非负整数,也就是内存共享标识。失败则返回-1;

                                         ii.         void *shmat(int shmid, const void *shmaddr, int shmflg);         --启动对内存空间的访问

shmid:共享内存标识。

shmaddr:指定共享内存连接到当前进程中的地址位置。

shmfig:访问模式。

返回值:若成功返回指向共享内存第一个字节的指针。若失败,返回-1;

                                       iii.         int shmdt(const void *shmaddr);     --共享内存分离

shmaddr:shmat返回的地址指针。

返回值:成功返回0。失败返回-1。

                                       iv.         int shmctl(int shmid, int cmd, struct shmid_ds *buf);        --内存控制

shmid:shmget返回的共享内存标识。

cmd:要采取的动作

IPC_STAT  把shmid_ds结构中的数据设置为共享内存的当前关联值

IPC_SET   如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值

IPC_RMID  删除共享内存段

                            buf:指向包含共享内存信息的结构体指针。

                            返回值:成功返回0;失败返回-1。

 

 

待续…

 

0 0
原创粉丝点击