首先,介绍一下linux环境下简单c程序的执行与运行,就以HelloWorld为例。

  1. 建立并编写一个.c文件。
    命令:touch helloWorld.c
    编写文件内容:vim helloWorld.c(当然,也可以用emacs,个人不喜欢emacs)
    文件中的内容:
#include <stdio.h>
#include <stdlib.h>

int main(){
  printf("Hello World!\n");
  exit(0);
}
  1. 编译运行。
    编译命令:gcc -o helloWorld helloWorld.c
    运行命令:./helloWorld
    结果:helloWorld运行结果

以上就是一个简单的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系统调用
    系统调用原型:
#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个字符。

Logo

更多推荐