当我们需要读取文件的某一个指定位置的数据,我们不可能顺序的把文件的内容都读到内存里面,然后再取出目标数据。
每个文件的描述字,都有一个当前位置。所以,当我们在需要读取某一个特定数据时,我们可以移动这个当前位置,移动到我们需要的位置,然后再读取。
所以,我们应该使用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
#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编译测试