首先,介绍一下linux环境下简单c程序的执行与运行,就以HelloWorld为例。
- 建立并编写一个.c文件。
命令:touch helloWorld.c
编写文件内容:vim helloWorld.c(当然,也可以用emacs,个人不喜欢emacs)
文件中的内容:
```c
#include
#include
int main(){ printf(“Hello World!\n”); exit(0); }
2. 编译运行。
编译命令:gcc -o helloWorld helloWorld.c
运行命令:./helloWorld
结果:![helloWorld运行结果](http://jinliangxx.oss-cn-beijing.aliyuncs.com/2019-04-28-075955.png)
以上就是一个简单的linuc c程序的建立与运行,非常简单,下面来学习linux c中关于文件的操作。
----------
***首先分析以下常用的文件路径***
- 应用程序
系统提供的应用程序的路径一般在/usr/bin或/usr/local/bin中
- 头文件
基本头文件在/usr/include,附加头文件一般在/usr/include/sys或/usr/include/linux中。
使用gcc -I的选项可以引入不在默认路径中的头文件。
例如:$gcc -I /usr/openwin/include hello.c
- 库文件
标准库文件一般在/lib或/usr/lib
库文件可以分为静态库(.a)和共享库(.so)
库文件的命名规范:以lib开头,后面部分指明库功能,后缀名说明库类型。
gcc的-l选项可以指定要搜索的库文件,-L选项指定库路径。
例如:gcc -o hello hello.c /usr/lib/libm.a
gcc -o hello hello.c -lm
gcc -o hello hello.c -L .usr/lib -l /usr/temp/lib/x.a
----------
**文件路径介绍完,正式进入文件的操作!!**
**系统调用的概念:**
Linux只需要少量函数就可以实现对文件和设备的访问和控制,这些函数被成为系统调用。
系统调用由Linux系统直接提供,是通向操作系统自身的接口。
Linux系统提供5个系统调用:**open,write,read,close,iotcl**
硬件的特有功能一般通过系统调用iotcl来完成。
- **write系统调用**
系统调用原型:
```c
#include <unistd.h>
size_t write(int fildes,const void *buf,size_t nbytes);
功能详解:将缓冲区buf的前nbytes个字节写入文件描述符fildes关联的文件中,返回实际写入的字节数(如果fildes大小不够或者有错返回将小于nbytes,返回0表示未写入任何数据,返回-1表示写入过程错误) 例子:
#include <unistd.h>
#include <stdlib.h>
int main()
{
if((write(1,"Here is some data\n",18)) != 18)
write(2,"A write error has occurred on file descriptor 1\n",46);
exit(0);
}
- read系统调用
系统调用原型:
#include <unistd.h> size_t read(int fildes,void *buf,size_t nbytes);
功能详解: 从文件描述符fildes关联的文件中读入nbytes个字节,并放入缓冲区buf中,返回实际读入的字节数(有可能小于nbytes,返回0表示未读入任何数据或者已经到文件尾,返回-1表示错误)。 例子:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(){
char buffer[128];
int nread;
nread = read(0, buffer, 128);
if(nread == -1)
write(2,"A read error has occurred\n",26);
if((write(1,buffer,nread)) != nread)
write(2,"A write error has occurred\n",27);
printf("Hello\n");
exit(0);
}
结果:
- open系统调用 系统调用原型:
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int open(const char *path,int oflags);
int open(const char *path,int oflags,mode_t mode);
功能详解: open系统调用创建一个新的文件描述符,如果调用成功将返回一个可以被read/write和其他系统调用使用的文件描述符。准备打开的设备或文件作为参数path传给函数,oflags参数用于指定文件打开所采取的动作。
- close系统调用和ioctl系统调用 系统调用原型:
close:
#include <unistd.h>
int close(int fildes);
ioctl:
#include <unistd.h>
int ioctl(int fildes,int cmd,...);
例子:打开led灯
ioctl(tty_fd,KDSETLED,LED_NUM|LED_CAP|LED_SCR);
结合使用例子: 1.文件复制
#include <unistd.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
char c;
int in,out;
in = open("file.in",O_RDONLY);
out = open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
while(read(in,&c,1) == 1)
write(out,&c,1);
exit(0);
}
下面是优化的代码:
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
char block[1024];
int in,out;
int nread;
in = open("file.in",O_RDONLY);
out = open("file.out",O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
while((nread == read(in,block,sizeof(block))) > 0)
write(out,block,nread);
exit(0);
}
优化的原理是,每次复制1个字符改为每次复制1024个字符。