gcc文件系统编程初阶<2>

ZDNet软件频道 时间:2002-08-06 作者:pianopan |  我要评论()
本文关键词:GCC
每个文件的描述字,都有一个当前位置。所以,当我们在需要读取某一个特定数据时,我们可以移动这个当前位置,移动到我们需要的位置,然后再读取。

当我们需要读取文件的某一个指定位置的数据,我们不可能顺序的把文件的内容都读到内存里面,然后再取出目标数据。

  每个文件的描述字,都有一个当前位置。所以,当我们在需要读取某一个特定数据时,我们可以移动这个当前位置,移动到我们需要的位置,然后再读取。

  所以,我们应该使用lseek函数,其函数原型如下:

===========================================
头文件
 #include<sys/types.h>
 #include<unistd.h>
原型
 off_t lseek(int sildes,off_t offset,int whence);
参数作用
 fildes 文件的描述字
 offset 偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)
 whence 当前位置的基点
  1.SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小。
  2.SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。
  3.SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小。
返回值
 如果系统调用成功,其返回值为从文件偷盗正要读写的位置之间的字节总数,如果系统调用失败,返回-1。
功能
 移动文件描述字的当前位置
注意
 1.当使用SEEK_END,SEEK_CUR时,偏移量才可以为负值。
 2.当文件描述字不为只读方式时,新的当前位置可以超过文件的尾部。
 3.本函数不能以管道或字符设备为对象来寻找当前位置。 

 为了描述这个函数,请看下面的例子(编译的方法GCC -o mywrite mywrite.c):

//mywrite.c
//www.beeship.com
//pianopan@beeship.com
//2002-2-4

#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>

#define ITEM_NAME_LENGTH 9
#define PERMS 0666
#define FILE_NAME "tempfile"
#define ITEM_COUNT 10

struct data_struct
{
  int data_id;
  char item_name[ITEM_NAME_LENGTH +1];
};

typedef struct data_struct RECORD;

char *item_name[]={
       "BEE","CAT","DOG",
       "PIG","MONKEY","DONKEY",
       "BIRD","RABBIT","HORSE",
       "SHEEP"};

main()
{
 int i;
 int file_id;
 RECORD record;

 if((file_id=open(FILE_NAME,O_WRONLY | O_TRUNC|O_CREAT,PERMS))==-1)
 {
  perror("open");
  exit(1);
 }

 printf("Open the files..... ");
 printf("The file was opened! ");

 /************************
    write the date
 *************************/
 for(i=ITEM_COUNT -1;i>=0;i--)
 {
  record.data_id=i;
  strcpy(record.item_name,item_name[i]);

  printf("ID=%d :WRITE "%s" ",i,item_name[i]);
 
  lseek(file_id,(long)i*sizeof(RECORD),SEEK_SET);
  write(file_id,(char*)&record,sizeof(RECORD));
 }

 printf("The command was completed! ");
 lseek(file_id,0L,SEEK_END);
 close(file_id);
 exit(0);
}

  应该说明的是,在GCC中,无论你是C语言源代码,还是C++源代码,对于两种注释方式都支持,所以,你可以在C语言里面使用C++的注释方法。

  这个例子中我们还是用了标准函数perror()来显示错误信息.

===========================================
头文件
 #include<stdio.h>
原型
 void perror(const char *s);
参数作用
 s 出错的信息 
功能
 输出错误的信息

  上面的程序,从文件的最末位开始,写入十个单词和他们的序号。然后我们用下面的程序从第一个数据开始,把上面的单词和序号读出来。编译方法GCC -o myread myread.c

//myread.c
//www.beeship.com
//pianopan@beeship.com
//2002-2-4

#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>

#define ITEM_NAME_LENGTH 9
#define PERMS 0666
#define FILE_NAME "tempfile"
#define ITEM_COUNT 10

struct data_struct
{
 int data_id;
 char item_name[ITEM_NAME_LENGTH +1];
};

typedef struct data_struct RECORD;


main()
{
 int i;
 int file_id;
 RECORD record;

 if((file_id=open(FILE_NAME,O_RDONLY,PERMS))==-1)
 {
  perror("open");
  exit(1);
 }

 printf("Open the files..... ");
 printf("The file was opened! ");

 for(i=1;i<10;i++)
 {
  lseek(file_id,(long)i*sizeof(RECORD),SEEK_SET);
  read(file_id,(char*)&record,sizeof(RECORD));
 
  printf("ID=%d :"%s" was be readed. ",i,record.item_name);
 }

 printf("The command was completed! ");
 lseek(file_id,0L,SEEK_END);
 close(file_id);
 exit(0);
}

  我们对上面的程序进行些修改,得到下面的这段代码,程序将根据使用者的参数作为序号,显示指定的单词和序号。编译方法:GCC -o myread1 myread1.c。

//myread1.c
//www.beeship.com
//pianopan@beeship.com
//2002-2-4

#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>

#define ITEM_NAME_LENGTH 9
#define PERMS 0666
#define FILE_NAME "tempfile"
#define ITEM_COUNT 10

struct data_struct
{
 int data_id;
 char item_name[ITEM_NAME_LENGTH +1];
};

typedef struct data_struct RECORD;


main(argc,argv)
int argc;
char *argv[];
{
 int i;
 int file_id;
 RECORD record;
 char c;

 if (argc !=2)
 {
  perror("input");
  exit(1);
 }

 if((file_id=open(FILE_NAME,O_RDONLY,PERMS))==-1)
 {
  perror("open");
  exit(1);
 }

 c=*(argv[1]);
 
 i=c-'0';

 printf("Open the files..... ");
 printf("The file was opened! ");

 lseek(file_id,(long)i*sizeof(RECORD),SEEK_SET);
 read(file_id,(char*)&record,sizeof(RECORD));

 printf("ID=%d :"%s" was be readed. ",i,record.item_name);


 printf("The command was completed! ");
 lseek(file_id,0L,SEEK_END);
 close(file_id);
 exit(0);
}


以上代码均通过RedHat7.2下GCC编译测试


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134