Linux系统开发 2 文件IO open() close() read() write() perror() lseek() fcntl() ioctl()

时间:2022-08-28 19:07:11

本文谢绝转载,原文来自http://990487026.blog.51cto.com


大纲
Linux系统开发

man 文档的使用
文件IO
open() 创建文件,指定权限位
open() 接收参数 创建文件
open() 传两个参数 第三个参数从内存取垃圾值
write()函数 向文件写数据
write()函数的覆盖操作
open()函数文件的追加
open() 创建文件,如果文件已经存在,就报错
测试一个程序最多能创建1021个文件,3个STDIN STDOUT STDERR已经存在了
通过ulimit命令也可以直接查询最多可以创建多少文件
修改ulimit -n 改变最大创建文件个数
最大最大能打开多少文件,取决于系统,据说是根据内存大小有关系
read write 文件复制(非二进制)
阻塞演示:输入输出必须等待回应才能执行下一步
非阻塞程序:
perror 报错函数
打印出错误的原因
Linux所有错误代码
文件lseek操作
lseek获取文件的大小
fcntl获取或者设置文件的访问控制属性
fcntl实例,以阻塞模式打开stdin,设置为非阻塞模式
ioctl 获取终端的行高 与 列宽
ioctl获取分辨率

习题




man page的使用

1、Standard commands (标准命令)2、System calls (系统调用)3、Library functions (库函数)4、Special devices (设备说明)5、File formats (文件格式)6、Games and toys (游戏和娱乐)7、Miscellaneous (杂项)8、Administrative Commands (管理员命令)9 其他(Linux特定的), 用来存放内核例行程序的文档。2016-08-01_20:02:34chunli@http://990487026.blog.51cto.com~$ man 3 printf2016-08-01_20:02:34chunli@http://990487026.blog.51cto.com~$ man 2 open


linux API函数 open函数,创建文件,指定权限位

2016-08-01_17:48:54root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>//linux apiman 2 open#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(void){int ret = open("abc",O_CREAT,0777);//设置权限位为777printf("%d\n",ret);return 0;}编译运行:2016-08-01_17:47:40root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app 3可以看到abc2016-08-01_17:49:17root@http://990487026.blog.51cto.com~/linux_c# ll total 16K-rwxr-xr-x 1 root   root      0 Aug  1 17:47 abc*-rwxr-xr-x 1 root   root   8.5K Aug  1 17:48 app*-rw-rw-r-- 1 chunli chunli  215 Aug  1 17:48 main.c查看系统的umask2016-08-01_17:50:00root@http://990487026.blog.51cto.com~/linux_c# umask0022为什么是755?0777 - 0022 == 0755我把umask搞一下2016-08-01_17:51:06root@http://990487026.blog.51cto.com~/linux_c# umask 02016-08-01_17:52:33root@http://990487026.blog.51cto.com~/linux_c# rm abc 2016-08-01_17:52:40root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app 32016-08-01_17:52:42root@http://990487026.blog.51cto.com~/linux_c# lltotal 16K-rwxrwxrwx 1 root   root      0 Aug  1 17:52 abc*-rwxrwxrwx 1 root   root   8.5K Aug  1 17:52 app*-rw-rw-r-- 1 chunli chunli  239 Aug  1 17:51 main.c


main函数接收参数,调用open函数创建文件

2016-08-01_18:23:50root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>//linux apiman 2 open#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(int argc,char **args){if(argc < 2){printf("请输入需要被创建的文件名\n");exit(1);//任何函数调用exit,程序直接退出}int ret = open(args[1],O_CREAT,0777);//设置权限位为777printf("%d\n",ret);return 0;}2016-08-01_18:23:55root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app  12332016-08-01_18:24:03root@http://990487026.blog.51cto.com~/linux_c# lltotal 16K-rwxr-xr-x 1 root   root      0 Aug  1 18:24 123*-rwxr-xr-x 1 root   root   8.5K Aug  1 18:24 app*-rw-rw-r-- 1 chunli chunli  406 Aug  1 18:23 main.c2016-08-01_18:24:06root@http://990487026.blog.51cto.com~/linux_c# umask00222016-08-01_18:24:10root@http://990487026.blog.51cto.com~/linux_c#


两个参数的open函数,第三个参数从内存取垃圾值

2016-08-01_18:25:19root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>//linux apiman 2 open#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(int argc,char **args){if(argc < 2){printf("请输入需要被创建的文件名\n");exit(1);//任何函数调用exit,程序直接退出}int ret = open(args[1],O_CREAT);//设置权限位为777printf("%d\n",ret);return 0;}编译运行:2016-08-01_18:24:55root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app  1233权限位很奇怪2016-08-01_18:24:57root@http://990487026.blog.51cto.com~/linux_c# ll---x--S--- 1 root   root      0 Aug  1 18:24 123*-rwxr-xr-x 1 root   root   8.5K Aug  1 18:24 app*-rw-rw-r-- 1 chunli chunli  401 Aug  1 18:24 main.c2016-08-01_18:25:20root@http://990487026.blog.51cto.com~/linux_c# umask0022


write()函数 向文件写数据

2016-08-01_19:35:52root@http://990487026.blog.51cto.com~/linux_c# rm 123  app 2016-08-01_19:35:56root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>#include <string.h>//linux apiman 2 open//open() and creat() return the new file descriptor, or -1 if an error occurred#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>//linux api     man 2 close#include <unistd.h>int main(int argc,char **args){if(argc < 2){printf("请输入需要被创建的文件名\n");exit(1);//任何函数调用exit,程序直接退出}//open函数返回文件描述符 0 1 2 =>STDIN STDOUT STDERRint fd = open(args[1],O_CREAT|O_RDWR,0644);//创建文件可读可写char buf[] = "Hello World!\n";write(fd,buf,strlen(buf));//写到当前进程文件描述符为fd的文件printf("%d\n",fd);return 0;}2016-08-01_19:35:58root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app  12332016-08-01_19:36:01root@http://990487026.blog.51cto.com~/linux_c# cat 123 Hello World!2016-08-01_19:36:08root@http://990487026.blog.51cto.com~/linux_c#


write()函数的覆盖操作 O_RDWR ,当open函数不需要create的时候,就不需要第3个函数

2016-08-01_19:40:53root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>#include <string.h>//linux apiman 2 open//open() and creat() return the new file descriptor, or -1 if an error occurred#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>//linux api     man 2 close#include <unistd.h>int main(int argc,char **args){if(argc < 2){printf("请输入需要被创建的文件名\n");exit(1);//任何函数调用exit,程序直接退出}//open函数返回文件描述符 0 1 2 =>STDIN STDOUT STDERR//int fd = open(args[1],O_CREAT|O_RDWR,0644);//创建文件可读可写int fd = open(args[1],O_RDWR);//创建文件可读可写char buf[] = "World!\n";write(fd,buf,strlen(buf));//写到当前进程文件描述符为fd的文件printf("%d\n",fd);return 0;}2016-08-01_19:39:27root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app  12332016-08-01_19:40:16root@http://990487026.blog.51cto.com~/linux_c# cat 123 World!orld!2016-08-01_19:40:19root@http://990487026.blog.51cto.com~/linux_c#


open()函数文件的追加 _RDWR|O_APPEND 

2016-08-01_19:42:36root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>#include <string.h>//linux apiman 2 open//open() and creat() return the new file descriptor, or -1 if an error occurred#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>//linux api     man 2 close#include <unistd.h>int main(int argc,char **args){if(argc < 2){printf("请输入需要被创建的文件名\n");exit(1);//任何函数调用exit,程序直接退出}//open函数返回文件描述符 0 1 2 =>STDIN STDOUT STDERR//int fd = open(args[1],O_CREAT|O_RDWR,0644);//创建文件可读可写int fd = open(args[1],O_RDWR|O_APPEND,0644);//创建文件可读可写//int fd = open(args[1],O_RDWR);//创建文件可读可写char buf[] = "Linux haha !\n";write(fd,buf,strlen(buf));//写到当前进程文件描述符为fd的文件printf("%d\n",fd);return 0;}2016-08-01_19:42:37root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app  12332016-08-01_19:42:40root@http://990487026.blog.51cto.com~/linux_c# cat 123 World!orld!Linux haha !2016-08-01_19:42:43root@http://990487026.blog.51cto.com~/linux_c#


open(args[1],O_CREAT | O_RDWR | O_EXCL,0644) 创建文件,如果文件已经存在,就报错

2016-08-01_19:49:44root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>#include <string.h>//linux apiman 2 open//open() and creat() return the new file descriptor, or -1 if an error occurred#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>//linux api     man 2 close#include <unistd.h>int main(int argc,char **args){if(argc < 2){printf("请输入需要被创建的文件名\n");exit(1);//任何函数调用exit,程序直接退出}int fd = open(args[1],O_CREAT | O_RDWR | O_EXCL,0644);//O_EXCL 如果文件已经存在,直接报错char buf[] = "Linux haha !\n";write(fd,buf,strlen(buf));//写到当前进程文件描述符为fd的文件printf("%d\n",fd);return 0;}2016-08-01_19:49:45root@http://990487026.blog.51cto.com~/linux_c# lltotal 20K-rw-r--r-- 1 root   root     26 Aug  1 19:42 123-rwxr-xr-x 1 root   root   8.7K Aug  1 19:49 app*-rw-rw-r-- 1 chunli chunli  705 Aug  1 19:49 main.c2016-08-01_19:49:46root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app  123-12016-08-01_19:49:48root@http://990487026.blog.51cto.com~/linux_c#


测试一个程序最多能创建多少个文件,1021个,其他3个STDIN STDOUT STDERR已经存在了

2016-08-01_20:24:55root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>#include <string.h>//linux apiman 2 open//open() and creat() return the new file descriptor, or -1 if an error occurred#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>//linux api     man 2 close#include <unistd.h>int main(int argc,char **args){//if(argc < 2)//{//printf("请输入需要被创建的文件名\n");//exit(1);//任何函数调用exit,程序直接退出//}char buf[10];int i = 0;while(1){sprintf(buf,"file_%d",++i);int fd = open(buf,O_CREAT,0644);//O_EXCL 如果文件已经存在,直接报错if(fd == -1){break;}else{printf("%d\t",i);if(i % 10 == 0)printf("\n");}}printf("\n");return 0;}2016-08-01_20:24:56root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app  12312345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010212016-08-01_20:24:58root@http://990487026.blog.51cto.com~/linux_c#



通过ulimit命令也可以直接查询最多可以创建多少文件

2016-08-01_20:26:24root@http://990487026.blog.51cto.com~/linux_c# ulimit -acore file size          (blocks, -c) 0data seg size           (kbytes, -d) unlimitedscheduling priority             (-e) 0file size               (blocks, -f) unlimitedpending signals                 (-i) 3823max locked memory       (kbytes, -l) 64max memory size         (kbytes, -m) unlimitedopen files                      (-n) 1024pipe size            (512 bytes, -p) 8POSIX message queues     (bytes, -q) 819200real-time priority              (-r) 0stack size              (kbytes, -s) 8192cpu time               (seconds, -t) unlimitedmax user processes              (-u) 3823virtual memory          (kbytes, -v) unlimitedfile locks                      (-x) unlimited2016-08-01_20:26:27root@http://990487026.blog.51cto.com~/linux_c#


修改ulimit -n 改变最大创建文件个数

2016-08-01_20:28:23root@http://990487026.blog.51cto.com~/linux_c# cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>#include <string.h>//linux apiman 2 open//open() and creat() return the new file descriptor, or -1 if an error occurred#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>//linux api     man 2 close#include <unistd.h>int main(int argc,char **args){//if(argc < 2)//{//printf("请输入需要被创建的文件名\n");//exit(1);//任何函数调用exit,程序直接退出//}char buf[10];int i = 0;while(1){sprintf(buf,"file_%d",++i);int fd = open(buf,O_CREAT,0644);//O_EXCL 如果文件已经存在,直接报错if(fd == -1){break;}else{printf("%d\t",i);if(i % 20 == 0)printf("\n");}}printf("\n");return 0;}2016-08-01_20:28:26root@http://990487026.blog.51cto.com~/linux_c# ulimit -n 20002016-08-01_20:29:34root@http://990487026.blog.51cto.com~/linux_c# ulimit -acore file size          (blocks, -c) 0data seg size           (kbytes, -d) unlimitedscheduling priority             (-e) 0file size               (blocks, -f) unlimitedpending signals                 (-i) 3823max locked memory       (kbytes, -l) 64max memory size         (kbytes, -m) unlimitedopen files                      (-n) 2000pipe size            (512 bytes, -p) 8POSIX message queues     (bytes, -q) 819200real-time priority              (-r) 0stack size              (kbytes, -s) 8192cpu time               (seconds, -t) unlimitedmax user processes              (-u) 3823virtual memory          (kbytes, -v) unlimitedfile locks                      (-x) unlimited2016-08-01_20:29:38root@http://990487026.blog.51cto.com~/linux_c# 2016-08-01_20:28:27root@http://990487026.blog.51cto.com~/linux_c# gcc -o app main.c  && ./app  123123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619972016-08-01_20:28:30root@http://990487026.blog.51cto.com~/linux_c#



最大最大能打开多少文件,取决于系统,据说是根据内存大小有关系

2016-08-01_20:31:00root@http://990487026.blog.51cto.com~/linux_c# cat /proc/sys/fs/file-max 97372


read write 文件复制(非二进制)

2016-08-01_21:24:08chunli@http://990487026.blog.51cto.com~/linux_c$ cat main.c //C标准头文件#include <stdio.h>#include <stdlib.h>#include <string.h>//linux api#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#define SIZE 8192int main(int argc,char **args){if(argc < 3){printf("参数不够\n");exit(1);//任何函数调用exit,程序直接退出}char buf[SIZE] = {0};int fd_src = 0;int fd_dest = 0;int len = 0;fd_src  =open(args[1],O_RDONLY);if(fd_src == -1){printf("open(args[1],O_RDONLY) 文件打开失败!\n");return fd_src;}fd_dest =open(args[2],O_CREAT | O_WRONLY | O_TRUNC,0755 );//创建文件,只写,截断if(fd_dest == -1){printf("open(args[2],O_CREAT | O_WRONLY | O_TRUNC,0755 ) 文件打开失败!\n");return fd_dest;}//成功返回督导的字符个数//读到末尾返回0//读失败返回-1while(len = read(fd_src,buf,sizeof(buf)) ) {write(fd_dest,buf,len);}return 0;}编译运行2016-08-01_21:24:11chunli@http://990487026.blog.51cto.com~/linux_c$ gcc main.c  -o app && ./app main.c  123查看复制的效果怎么样2016-08-01_21:24:13chunli@http://990487026.blog.51cto.com~/linux_c$ cat 123 //C标准头文件#include <stdio.h>#include <stdlib.h>#include <string.h>//linux api#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#define SIZE 8192int main(int argc,char **args){if(argc < 3){printf("参数不够\n");exit(1);//任何函数调用exit,程序直接退出}char buf[SIZE] = {0};int fd_src = 0;int fd_dest = 0;int len = 0;fd_src  =open(args[1],O_RDONLY);if(fd_src == -1){printf("open(args[1],O_RDONLY) 文件打开失败!\n");return fd_src;}fd_dest =open(args[2],O_CREAT | O_WRONLY | O_TRUNC,0755 );//创建文件,只写,截断if(fd_dest == -1){printf("open(args[2],O_CREAT | O_WRONLY | O_TRUNC,0755 ) 文件打开失败!\n");return fd_dest;}//成功返回督导的字符个数//读到末尾返回0//读失败返回-1while(len = read(fd_src,buf,sizeof(buf)) ) {write(fd_dest,buf,len);}return 0;}2016-08-01_21:24:16chunli@http://990487026.blog.51cto.com~/linux_c$



阻塞演示:输入输出必须等待回应才能执行下一步

chunli@ubuntu:~/linux_c$ cat main.c #include <sys/types.h>#include <sys/stat.h>#include <unistd.h>int main(void){int len  = 0;char buf[30] = {0};len = read(STDIN_FILENO,buf,sizeof(buf));write(STDOUT_FILENO,buf,len);return 0;}chunli@ubuntu:~/linux_c$ gcc main.c  && ./a.out hahahahahahachunli@ubuntu:~/linux_c$



非阻塞程序:

chunli@ubuntu:~/linux_c$ cat main.c #include <stdio.h>#include <stdlib.h>//exit#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>//perror#define MSG_TRY "try again \n"int main(void){char buf[10] = {0};int fd = 0;int n = 0;fd = open("/dev/tty",O_RDONLY | O_NONBLOCK);if(fd < 0){perror("open /dev/tty");exit(1);}tryagain:n = read(fd,buf,sizeof(buf));if(n < 0){if(errno == EAGAIN){sleep(3);write(STDOUT_FILENO,MSG_TRY,strlen(MSG_TRY));goto tryagain;}perror("read /dev/tty");exit(2);}write(STDOUT_FILENO,buf,n);close(fd);return 0;}编译运行:chunli@ubuntu:~/linux_c$ gcc main.c  && ./a.out hellotry again hellochunli@ubuntu:~/linux_c$



tty

chunli@ubuntu:~$ tty/dev/pts/0chunli@ubuntu:~$ whochunli   pts/0        2016-08-02 10:35 (10.11.12.1)chunli   pts/5        2016-08-02 08:56 (10.11.12.1)chunli@ubuntu:~$ sudo echo `date` >>  /dev/ttyTue Aug 2 11:35:06 CST 2016chunli@ubuntu:~$


perror 报错函数,全局变量errno,perrno去找这个数字,报出原因

chunli@ubuntu:~/linux_c$ cat main.c #include <stdio.h>#include <stdlib.h>//exit#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>//perrorint main(void){        int fd = open("123",O_WRONLY);        if(fd<0)        {                printf("错误代码是:%d\n",errno);                perror("出错啦");                exit(-1);        }        return 0;}chunli@ubuntu:~/linux_c$ gcc main.c  && ./a.out 错误代码是:2出错啦: No such file or directorychunli@ubuntu:~/linux_c$


打印出错误的原因

chunli@ubuntu:~/linux_c$ cat main.c #include<stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>int main(void){        int fd = open("123",O_WRONLY);        if(fd<0)        {                printf("错误代码是:%d\n",errno);printf("打印出错误的原因%s \n",strerror(errno));                //perror("出错啦");                exit(-1);        }        return 0;}chunli@ubuntu:~/linux_c$ gcc main.c  && ./a.out 错误代码是:2打印出错误的原因No such file or directory chunli@ubuntu:~/linux_c$


Linux所有错误代码

chunli@ubuntu:~/linux_c$ sudo find / -iname *errno-base* /usr/src/linux-headers-3.13.0-92/include/uapi/asm-generic/errno-base.h/usr/src/linux-headers-3.19.0-25/include/uapi/asm-generic/errno-base.hchunli@ubuntu:~/linux_c$ cat /usr/src/linux-headers-3.19.0-25/include/uapi/asm-generic/errno-base.h#defineEPERM 1/* Operation not permitted */#defineENOENT 2/* No such file or directory */#defineESRCH 3/* No such process */#defineEINTR 4/* Interrupted system call */#defineEIO 5/* I/O error */#defineENXIO 6/* No such device or address */#defineE2BIG 7/* Argument list too long */#defineENOEXEC 8/* Exec format error */#defineEBADF 9/* Bad file number */#defineECHILD10/* No child processes */#defineEAGAIN11/* Try again */#defineENOMEM12/* Out of memory */#defineEACCES13/* Permission denied */#defineEFAULT14/* Bad address */#defineENOTBLK15/* Block device required */#defineEBUSY16/* Device or resource busy */#defineEEXIST17/* File exists */#defineEXDEV18/* Cross-device link */#defineENODEV19/* No such device */#defineENOTDIR20/* Not a directory */#defineEISDIR21/* Is a directory */#defineEINVAL22/* Invalid argument */#defineENFILE23/* File table overflow */#defineEMFILE24/* Too many open files */#defineENOTTY25/* Not a typewriter */#defineETXTBSY26/* Text file busy */#defineEFBIG27/* File too large */#defineENOSPC28/* No space left on device */#defineESPIPE29/* Illegal seek */#defineEROFS30/* Read-only file system */#defineEMLINK31/* Too many links */#defineEPIPE32/* Broken pipe */#defineEDOM33/* Math argument out of domain of func */#defineERANGE34/* Math result not representable */




文件lseek操作,扩展一个文件,需要一次写操作

chunli@ubuntu:~/linux_c$ cat main.c // man 2 lseek#include <stdio.h>#include <stdlib.h>//exit#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>int main(void){int fd = open("abc",O_RDWR);if(fd < 0){perror("open abc ");exit(-1);}lseek(fd,0x1000,SEEK_SET);write(fd,"a",1);close(fd);return 0;}chunli@ubuntu:~/linux_c$ chunli@ubuntu:~/linux_c$ touch abcchunli@ubuntu:~/linux_c$ gcc main.c  && ./a.outchunli@ubuntu:~/linux_c$ ls -l total 20-rw-rw-r-- 1 chunli chunli 4097 Aug  2 15:59 abc-rwxrwxr-x 1 chunli chunli 8805 Aug  2 15:59 a.out-rw-rw-r-- 1 chunli chunli  347 Aug  2 15:59 main.cchunli@ubuntu:~/linux_c$ 用od 查看文件的内容chunli@ubuntu:~/linux_c$ od -tc abc 0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0*0010000   a0010001chunli@ubuntu:~/linux_c$





lseek获取文件的大小

chunli@ubuntu:~/linux_c$ cat main.c #include <stdio.h>#include <stdlib.h>//exit#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>int main(void){int fd = open("abc",O_RDWR);if(fd < 0){perror("open abc ");exit(-1);}lseek(fd,0x1000,SEEK_SET);write(fd,"a",1);close(fd);fd = open("main.c",O_RDWR);if(fd < 0){perror("open hello");exit(-1);}printf("hello size = %ld\n",lseek(fd,0,SEEK_END));return 0;}chunli@ubuntu:~/linux_c$ gcc main.c  && ./a.outhello size = 485chunli@ubuntu:~/linux_c$




fcntl获取或者设置文件的访问控制属性

fcntl实例,以阻塞模式打开stdin,设置为非阻塞模式

chunli@ubuntu:~/linux_c$ cat main.c #include <stdio.h>#include <stdlib.h>//exit#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#define MSG_TRY "try again \n"int main(void){char buf[100]= {0};int n  = 0;int flags;flags = fcntl(STDIN_FILENO,F_GETFL);flags |= O_NONBLOCK;if(fcntl(STDIN_FILENO,F_SETFL,flags) == -1){perror("fcntl");exit(-1);}tryagain:n = read(STDIN_FILENO,buf,sizeof(buf));if(n < 0){if(errno == EAGAIN){sleep(1);write(STDOUT_FILENO,MSG_TRY,strlen(MSG_TRY));goto tryagain;}perror("read stdin");exit(2);}write(STDOUT_FILENO,buf,n);return 0;}chunli@ubuntu:~/linux_c$ gcc main.c  && ./a.outdadastry again dtry again dadasdchunli@ubuntu:~/linux_c$


ioctl 获取终端的行高 与 列宽

chunli@ubuntu:~/linux_c$ cat main.c #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/ioctl.h>int main(void){struct winsize size;if(!isatty(STDOUT_FILENO))//如果不是终端就退出{exit(1);}if(ioctl(STDOUT_FILENO,TIOCGWINSZ,&size) <0){perror("ioctl TIOCGWINSZ error");}printf("行高%d\t列宽%d\n",size.ws_row,size.ws_col);return 0;}chunli@ubuntu:~/linux_c$ gcc main.c  && ./a.out行高43列宽173chunli@ubuntu:~/linux_c$

【见图】

Linux系统开发 2 文件IO open() close()  read() write()  perror()  lseek()  fcntl()  ioctl()

Linux系统开发 2 文件IO open() close()  read() write()  perror()  lseek()  fcntl()  ioctl()




ioctl获取分辨率

chunli@ubuntu:~/linux_c$ cat main.c #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <linux/fb.h>int main(void){int fd;struct fb_var_screeninfo fb_info;fd = open("/dev/fb0",O_RDONLY);if(fd < 0){perror("open /dev/fb0");exit(-1);}ioctl(fd,FBIOGET_VSCREENINFO,&fb_info);printf("tty分辨率是%d * %d \n",fb_info.xres,fb_info.yres);close(fd);return 0;}chunli@ubuntu:~/linux_c$ gcc main.c  &&  sudo ./a.outtty分辨率是800 * 600 chunli@ubuntu:~/linux_c$



习题





* 在系统头文件中查找flags和mode参数用到的这些宏定义的值是多少。把这些宏定义按

位或起来是什么效果?为什么必选项只能选一个而可选项可以选多个?


* 请按照下述要求分别写出相应的open调用。


打开文件/home/xingwenpeng/itcast.txt用于写操作,以追加方式打开

打开文件/home/xingwenpeng/itcast.txt用于写操作,如果该文件不存在则创建它

打开文件/home/xingwenpeng/itcast.txt用于写操作,如果该文件已存在则截断为0字

节,如果该文件不存在则创建它

打开文件/home/xingwenpeng/itcast.txt用于写操作,如果该文件已存在则报错退出,

如果该文件不存在则创建它


* 创建一个10M的空文件


* 实现输出重定向,当C标准printf打印时,打印到你指定的test文件里


* mycp拷贝命令实现。(思考如何拷贝目录呢?)


* 获取当前图形界面的屏幕分辨率


本文出自 “李春利” 博客,谢绝转载!