Linux-文件操作

Linux-文件操作(open、write、read、close、iotcl)

Posted by Jinliang on March 19, 2018

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

  1. 建立并编写一个.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个字符。