Linux io

=========================================================================================
[1] >> 文件? 
[
<>	目录文件--d = directory  
<>	字符设备文件--c = char   
<>	块设备文件--b = block
<>	管道文件--p = pipe
<>	套接字文件--s = socket
<>	符号链接文件--l = ln
]
=========================================================================================
[2] >> 文件流FILE? 
-->>流程讲解:"word11 word12"写到text1.txt的"word8"后面
--------------------------------------------------------------------------------------------
SEEK_SET======⇳	  文件text1.txt 
			 [word1  word2  word3     ]  
			 [word4  word5  word7     ] 			              缓冲区队列/文件流
			 [word8  word9  word10 EOF]	 		     =======[word11 word12     ] <--> 输入设备
			 [    ⇳             ⇳  ⇳ ][    ⇳             ⇳  ⇳ ]               ⇳
				  ⇳		        ⇳  =====文件结束符    ⇳
     		   SEEK_CUR	    SEEK_END                  ⇳
				   ⇳						          ⇳
				   ====================================
<>//注意:文件流的指向文件内部某个位置 --> 文件流=针管;文件=皮肉;针管满后再向皮肉某个位置输送
<>//注意:文件流满,才会fflush操作
<>//注意:文件流向文件写数据,是写到文件内部位置指针的后面,也就是文件流指向的位置,也就是"word8"后面
<>//注意:文件结束符EOF != SEEK_END ,SEEK_END 在EOF前面一个字节
--------------------------------------------------------------------------------------------
-->>系统预定义文件流:
[
<>	 标准输入流	STDIN_FILENO  stdin   0
<>	 标准输出流	STDOUT_FILENO stdout  1
<>	 标准错误流	STDERR_FILENO stderr  2
]
<>-->>FILE*fopen(const char *path,const char*mode); [r/r+/w/w+/a/a+,a=append=文件末尾写]	[return :NULL --> error]
<>-->>int fclose(FILE*stream);  [EOF = error]
<>-->>size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); [return:the number of items successfully read ;0 is error or end of file]  
<>-->>size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);[return:the number of items successfully  written ; 0 is error or end of file]
<>-->>int fflush (FILE *fp); [EOF-->error] [流满,换行,fflush --> 写入文件(效率高)]
<>-->>long ftell(FILE *stream); [得到文件内部位置指针的位置 : 数据流被fflush到文件内部位置指针的后面]  [return : -1--> error]
<>-->>int fprintf(FILE *stream, const char *format, ...);[return : 写入的字节个数] 
<>-->>int feof(FILE *stream);[检测流上的文件结束符,通常判断是否读到文件末尾] [return:0-->未末尾;!0-->末末尾]
<x>-->>long fseek(FILE *stream,long offset, int whence);[return : 0-->success ;-1 --> error] 
<>-->>打开ubuntu串口终端(ctrl + alt + fn) ; 切换到ubuntu桌面(ctrl + alt + f7)
<>[SEEK_SET  文件开头]
<>[SEEK_CUR  文件当前]
<>[SEEK_END  文件末尾]
<>[重定位文件内部位置指针] 
<>[后续数据写入将在位置指针后面接入]
-->>注意:fread与fwrite不能同时在一个流里面操作,因为流是单向的,必须写完后,关闭流后,再重新打开文件流进行读取
============================================================================================================
[3] >> 其他重要函数?
<>-->>void perror(const char *s);  [能自动输出错误信息]
<>-->>int sprintf(char *str, const char *format, ...); [return : 写入的字节数]
==============================================================================================
[4] >> Linux系统提供的文件IO接口 ?
<>-->>没有流缓冲区机制,返回文件描述符fd
<>-->>文件IO函数功能更强大,能打开更多种类文件 [文件流只能打开普通文件]
<>-->>int open(constchar*pathname,int flags); [0=stdin;1=stdout;2=error;后续打开文件分配3.4.5.....] [return:-1 --> error] 
[flags参数:
	//必选
	<>O_RDONLY只读模式 
	<>O_WRONLY只写模式 
	<>O_RDWR读写模式 
	//可选
	<>O_APPEND每次写操作都写入文件的末尾 
	<x>O_CREAT如果指定文件不存在,则创建这个文件 
	<>O_EXCL如果要创建的文件已存在,则返回-1,并且修改errno的值
	<x>O_NONBLOCK or O_NDELAY表示非阻塞模式
]
<>-->>ssize_t write(int fd, const void *buf, size_t count);   [-1-->error]
<>-->>ssize_t read(int fd, void *buf, size_t count);       [-1-->error]
<>-->>off_t lseek(int fd, off_t offset, int whence);   [-1 --> error]
<>[SEEK_SET  文件开头]
<>[SEEK_CUR  文件当前]
<>[SEEK_END  文件末尾]
<>[重定位文件内部位置指针] 
<>[如果执行成功,后续数据将写入以whence为基准,偏移offset(指针偏移量)个字节的位置]
<>-->>int close(int fd);  [-1-->error]
<x>-->>注意:read,write不能同时进行,必须fd关闭再操作
==================================================================================================

==================================================================================================
[5] >> 目录流DIR ?
<>-->>目录(directory)
-->>目录流操作流程:
	     [file/目录下有如下9个文件]
	     ⇳
	     ⇳          DIR(第一次readdir)		
	     ⇳           ⇳       DIR(2次readdir)
	     ⇳           ⇳        ⇳      DIR(3次readdir)
	     ⇳           ⇳        ⇳       ⇳ 
   		file/ -->>[text1.c  text2.c text3.c]
 				  [text4.c  text5.c text6.c]
 				  [text7.c  text8.c text9.c]
//注意:readdir()可以从DIR中读取到文件属性后,DIR都会自动指向下一个文件

<>-->>DIR *opendir(const char *name); [NULL --> error]
<x:>-->>struct dirent *readdir(DIR *dirp); [NULL --> error]
[
  struct dirent {
               ino_t          d_ino;       /* inode number */
               off_t          d_off;       /* offset to the next dirent */<>
               unsigned short d_reclen;    /* length of this record(记录) */
               unsigned char  d_type;      /* type of file; not supported
                                              by all file system types */
               char           d_name[256]; /* filename */
           };
]
<>-->>int closedir(DIR *dirp); [return : -1 -->error;]
==================================================================================================
[6] >><>-->> /lib 存放动态库文件
<>-->> /usr/lib 用户程序的库文件
<>-->>静态库文件格式:lib名称.a 
[
	<>ar -crs libtext.a text.o  [ar建立档案]
	<>nm libtext.a [list symbols from object files]
	<>gcc main.o -L -l libtext.a  [-L+库路径 ; -l+库名 ; -I+头文件路径]
]

<>-->>动态库文件格式:lib名称.so
[
	<x>gcc -c -fPIC text.c [表示编译为位置独立的代码]  
	<x>gcc text.o -shared -o libtext.so 
	<>nm libtext.so 
	<>gcc main.o -L -l libtext.so  [L--路径 ; l--库名]
]
==================================================================================================
[7] >> system v IPC ?
<>-->>[IPC = in process  communicate ] [system = 系统 = 内核中]
<>-->>IPC = {共享内存(shm)、消息队列(msg)和信号量(sem)}
<>-->>ipcs命令  [显示所有IPC对象]
<>-->>ipcs -l  [查看最大IPC空间是多少]
<>-->>ipcrm [-M -m -S -s -Q -q] [key值 id值]
[
	//先获取的key,所以key是大写,id是小写
	ipcrm -M key 根据key删除内存类型ipc
	ipcrm -m id根据pic号删除内存型ipc
	ipcrm -Q key根据键值删除队列ipc
	ipcrm -q id根据pic号删除队列型ipc
	ipcrm -S key根据键值删除信号量ipc
	ipcrm -s id根据pic号删除信号量ipc
	//id;key;m=内存类型;q=队列类型;s=信号量类型
]
[
================================================================================================================
	<x>共享内存是Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。
	[
		<>1>>key_t ftok(const char *pathname, int proj_id); 
		[
			id是子序号。虽然是int类型,但是只使用8bits(1-255)。
			在一般的UNIX实现中,是将文件的索引号取出,前面加上子序号得到key_t的返回值。
			如指定文件的索引节点号为65538,换算成16进制为0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002
		]
		<>2>>int shmget(key_t key, size_t size, int shmflg);[return :-1 --> error;] 
		[
			函数说明--得到/创建一个共享内存对象并返回共享内存标识符
			函数传入值
					key -- 0(IPC_PRIVATE):会建立新共享内存对象 / ftok返回的IPC键值
					size -- 大于0的整数:新建的共享内存大小,以字节为单位 / 0:只获取共享内存时指定为0 [ipcs -l]
					shmflg 
						0:取共享内存标识符
						IPC_CREAT:创建新的消息队列
						IPC_EXCL:与IPC_CREAT一同使用,表示如果要创建的消息队列已经存在,则返回错误。
			成功:返回共享内存的标识符
			出错:-1,错误原因存于errno中
		]
		<>3>>void *shmat(int shmid, const void *shmaddr, int shmflg);  
		[
			函数说明--连接共享内存标识符为shmid的共享内存,连接成功后把共享内存区对象映射到调用进程的地址空间,随后可像本地空间一样访问
			函数传入值
					shmid--共享内存标识符
					shmaddr--指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置
					shmflg--SHM_RDONLY:为只读模式,其他为读写模式
			函数返回值
					成功:附加好的共享内存地址
					出错:-1,错误原因存于errno中
		]
		<>4>>int sprintf(char *str, const char *format, ...); 
		<>5>>int printf(const char *format, ...); [return : -1-->error]
		<x>6>>int shmdt(void*shmaddr); [return:-1-->error;] 
		<x>7>>int shmctl(int shmid, int cmd, struct shmid_ds *buf);[return:-1-->error;0-->success]//删除共享内存 
		[
			函数说明--完成对共享内存的控制
			函数传入值
					shmid--共享内存标识符
					cmd
						IPC_STAT--得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
						IPC_SET--改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内
						IPC_RMID--删除这片共享内存
					buf--共享内存管理结构体
					函数返回值
						成功:0
						出错:-1,错误原因存于error中
		]
]
========================================================================================================
		消息队列
		[
			-->>消息队列的使用流程
			[
				<>1>>key_t ftok(const char *pathname, int proj_id);[前面已介绍]
				<x>2>>int msgget(key_t key, int msgflg); //获取id ,返回id,msgflg = 权限[return:-1-->error]
				[
					功能--用于创建一个新的或打开一个已经存在的消息队列,此消息队列与key相对应
					key--函数ftok的返回值或IPC_PRIVATE
					msgflag
						IPC_CREAT:创建新的消息队列
						IPC_CREAT值,若没有该队列,则创建一个并返回新标识符;若已存在,则返回原标识符。
                		IPC_EXCL值,若没有该队列,则返回-1;若已存在,则返回0。
					返回值--调用成功返回队列标识符,否则返回-1.
				]
				<x>3>>int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);[return:-1-->error;0-->success]
				[
					功能--将一个新的消息写入队列
					msqid--队列标识符
					msgp
						struct msgbuf {
						long mtype; /* 消息类型,必须 > 0 */
						char mtext[1]; /* 消息文本 */
						};
					msgsz--msgp结构体大小
					msgflg:这个参数依然是控制函数行为的标志
							0--表示忽略;
							IPC_NOWAIT--如果消息队列为空,则立即返回一个ENOMSG,并将控制权交回调用函数的进程。		
					成功执行--返回0,失败返回-1													
				]
				<x>4>>ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);[return:-1-->error;接收到的字节数]
				[
						功能--从消息队列中读取消息,从消息队列发送结构体搬运到接收结构体
						msqid--队列标识符
						msgp
							struct msgbuf {
							long mtype; /* 消息类型,必须 > 0 */
							char mtext[1]; /* 消息文本 */
							};
						msgsz--结构体大小
						msgtyp等于0 则返回队列的最早的一个消息。
						msgtyp大于0,则返回其类型为msgtyp的第一个消息。
						msgtyp小于0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息。
				]
				<>5>>int msgctl(int msqid, int cmd, struct msqid_ds *buf);[ds = data =struct] [-1 ---> error]
				[
					msqid--队列标识符
					cmd
						IPC_STAT--读取消息队列的数据结构msqid_ds,并将其存储在buf指定的地址中。
						IPC_SET--设置消息队列的数据结构msqid_ds中的ipc_perm元素的值。这个值取自buf参数。
					I	PC_RMID--从系统内核中移走消息队列。
					0 ,如果成功;- 1,如果失败:
				]
			]
	========================================================================================================
	信号量数组
			[
				-->>信号灯使用步骤
				<>1>>key_t ftok(const char *pathname, int proj_id); [前面已经介绍]
				<>2>>int semget(key_t key, int nsems, int semflg);
				[
					key--所创建或打开信号量集的键值。
					nsems--创建的信号量集中的信号量的个数,该参数只在创建信号量集时有效。
					semflg--调用函数的操作类型
					-1--error
				]
				<x>3>>int semctl(int semid, int semnum, int cmd, …);//设置信号灯值 [retrurn:-1-->error;0-->success]
				[
						功能--信号量数组中的某个信号量的操作(赋初值,删除...)
						semid--信号量数组标识符
						semnum--操作信号量数组的第几个信号量
						cmd
							IPC_SET -- 信号量数组中第semnum个信号量赋值为semun.val 
							IPC_RMID  
							IPC_STAT
				        返回值:如果成功,则为一个正数。如果失败,则为-1
				        union semun {
				               int              val;    /* Value for SETVAL */
				               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
				               unsigned short  *array;  /* Array for GETALL, SETALL */
				               struct seminfo  *__buf;  /* Buffer for IPC_INFO
				           };	
				]
				<x>4>>int semop(int semid, struct sembuf *sops, unsigned nsops); 
				[
					semid--信号量数组标识符
					struct sembuf{
			           unsigned short sem_num; //sem_num:操作信号在信号集中的编号,第一个信号的编号是0。
			           short          sem_op; 
			           short          sem_flg; //IPC_NOWAIT 非阻塞;SEM_UNDO避免资源永远锁定。
			           }
			       nsops--信号操作结构的数量
				]
				nsops = numbers of sem
]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值