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。
待续…
- Linux 高级编程之小结(一)
- 高级编程之网络编程(一)
- 高级编程之目录(一)
- 高级编程之进程(一)
- 高级编程之线程(一)
- linux内核编程接口小结(一)
- Linux之CGI编程小结
- Linux-C高级编程(1)文件操作(一)
- linux进程控制(一)--unix环境高级编程读书笔记
- linux信号(一)--unix环境高级编程读书笔记
- C#高级编程----小结
- C#高级编程小结
- unix高级编程之-命令行参数(实践一)
- Python高级编程之数据库sqlite3(一)
- 高级编程之进程间通信(一)
- unix环境高级编程之信号篇(一)
- unix环境高级编程之线程篇(一)
- linux小结(一)
- 禁用form表单中所有控件
- nyoj 苹果
- HDU 5317 RGCDQ
- hdu 5325 Crazy Bobo 乱搞+搜索
- VS2008设置内存断点
- Linux 高级编程之小结(一)
- eclipse下安装tomcat以及可能遇到的404问题
- CentOS 最小化安装后初始化网络
- Linux查看网络状态
- java实现归并排序
- poj 3723 最大权森林 最小生成树的运用
- zookeeper配置
- HDU 5319 Painter
- 深圳的天气真不错