lseek函数原型为int lseek(int fd,int offset, int whence),fd为定位文件的描述符,offset为偏移量,如果是正数,则向文件末尾偏移,负数时,则向文件头偏移,但是不能超出文件的范围,whence为参考点,

SEEK_SET为文件头,SEEK_END为文件末尾,SEEK_CUR为文件当前操作位置返回值为操作后文件操作位置对文件头的偏移量,如果需要计算文件大小时,可以把文件操作位置移动到文件末尾,返回值即为文件的大小(字节数)

需要注意,求文件长度时把文件的操作位置移动到文件末尾,这时要在进行操作,需要把文件操作位置移回到文件头

现在可以来做一题目:解析/etc/passwd这个文件,把ect下面的用户名解析出来,并且写入另外一个文件中

这里涉及一个算法,观察每一行,会发现,我们需要的东西是冒号前面的字符,所以可以调用strchr这个函数来进行查找,strchr()这个函数的函数原型是char * strchr(const char *s,int c);返回值是函数操作的指针,这里要注意,int c是四个字节,足够容纳一个字符串,这里是继承unix的函数的接口,所以这个(笔者想,这也许可以用来制造计算机病毒,因为char是一个字节,还有三个字节可以用,如果调用strchr()函数时设计一个后门,是程序运行到strchr函数,查找其他三个字节,进而跳转到自己写的汇编代码~~笔者功力不足,但自觉告诉我这种方法可行)

回到正题,利用strchr查找到之后,指针指向冒号,将冒号改为'\0',再用printf("%s")进行打印即可

代码示例代码

include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h> int main(void)
{
int fd1,fd2,size,f1,f2,len;
char *buf,*tem,*con; fd1 = open("/etc/passwd",O_RDONLY); if(fd1<0)
{
printf("openfile fail\n");
return -1;
} fd2 = open("test2",O_WRONLY|O_CREAT|O_APPEND,777);
if(fd2<0)
{
printf("create test2 fail\n");
return -1;
} len = lseek(fd1,0,SEEK_END);
lseek(fd1,0,SEEK_SET); buf = (char *)malloc(len);
if(buf==NULL)
{
printf("malloc fail\n");
return -1;
} memset(buf,0,len); size = read(fd1,buf,len);
if(size <0)
{
printf("read fail\n");
return -1;
} tem = buf;
while(1)
{
con = strchr(tem,':');//查找字符串
if(con!=NULL) //字符串找到了
{
*con = '\n'; //将该处设为回车
*(con+1)='\0';//将该处设为打印时的断点 f1 = write(fd2,tem,strlen(tem));//写入文件
if(f1 <0)
{
printf("write fail\n");
return -1;
} tem = con+2;
con = strchr(tem,'\n');
if(con !=NULL)
{
tem = con +1; }
else
{
break;
}
}
else
{
break;
}
}
close(fd1);
close(fd2);
free(buf); return 0;
}

注意这里写入文件test2编译可以执行,但是不能执行第二次,原因是没有权限,所以要调用命令chmod 777 text2将文件的权限全部打开,才能重复执行代码,这里调用的lseek函数用来计算文件的总长度,返回值即是文件的长度,在调用malloc()分配相应的字节数,这样就可以一次性读完了文件,而不用重复读写,这种方法虽然能够提高代码运行的速度,但是在大文件的时候,文件可能太大,会占用过多的系统资源,所以,读取文件要进行适当的选择,但是一般是都一次性读取

例2:读取该文件中间五十个字节:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h> int main(void)
{
int fd1,fd2,size,mid,slen;
char *buf; fd1 = open("/etc/passwd",O_RDONLY);
if(fd1 < 0)
{
printf("open fail\n");
return -1;
} fd2 = open("chazao",O_CREAT|O_RDWR,777);
if(fd2 < 0)
{
printf("open fail\n");
return -1;
} fd2 = open("chazao",O_CREAT|O_RDWR,777);
if(fd2 < 0)
{
printf("create chazao fail\n");
return -1;
} size = lseek(fd1,0,SEEK_END);
mid = size/2;
lseek(fd1,-(mid+25),SEEK_END);//这里负号表示向文件头偏注意一定是负号 buf = (char *)malloc(50);
if(buf ==NULL)
{
printf("malloc fail\n");
return -1;
}

版权所有,转载请注明链接地址:http://www.cnblogs.com/fengdashen/p/3304046.html

文件I/O操作(2)的更多相关文章

  1. 用 JSP 实现对文件的相关操作

    前段时间一直忙着作业,实验,动手的时间真是少之又少,今天终于可以继续和大家分享关于 JSP 的学习心得. 简单总结一下吧: JSP 理论性很强,感觉就是纯语法. 我更偏向于实际编写代码,这样更容易理解 ...

  2. PHP文件相关的操作函数——目录操作

    1.有关文件类型的函数 PHP是以UNIX的文件系统为模型的,因此在Windows系统中我们只能获得“file”.“dir”或者“unknown”三种文件类型.而在UNIX系统中,我们可以获得“blo ...

  3. C#对文件/目录的操作:Path、File、Directory、FileStream、StreamReader、StreamWriter等类的浅析

    以下类的命名空间都是:System.I/0; 一.Path:主要对文件路径的操作! 常用方法: String path=@"C:\a\b\c\123.txt"; 1-1.Path. ...

  4. 无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120)的解决方法

    无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问.)” (Microsoft SQL Server,错误: 5120)的解决方法   问题描述: 在附加数据库到sql server时,附 ...

  5. java io流 对文件夹的操作

    java io流 对文件夹的操作 检查文件夹是否存在 显示文件夹下面的文件 ....更多方法参考 http://www.cnblogs.com/phpyangbo/p/5965781.html ,与文 ...

  6. php对xml文件进行CURD操作

    XML是一种数据存储.交换.表达的标准: - 存储:优势在于半结构化,可以自定义schema,相比关系型二维表,不用遵循第一范式(可以有嵌套关系): - 交换:可以通过schema实现异构数据集成: ...

  7. 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】

    一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...

  8. Python::OS 模块 -- 文件和目录操作

    os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...

  9. INI 文件的读写操作

    在C#中对INI文件进行读写操作,在此要引入using System.Runtime.InteropServices; 命名空间,具体方法如下: #region 变量 private static r ...

  10. Android 对 properties文件的读写操作

    -. 放在res中的properties文件的读取,例如对放在assets目录中的setting.properties的读取:PS:之所以这里只是有读取操作,而没有写的操作,是因为我发现不能对res下 ...

随机推荐

  1. SpringMVC注解@RequestParam(转)

    鸣谢:http://shawnccx.iteye.com/blog/730239 -------------------------------------------------- 在SpringM ...

  2. SQL SERVER数据导入

    我的博客已好久没有文字方面的记载了,好歹昨天已经结束软件设计师的考试了,今天怎么说也需要锻炼自己的写作能力.不然真怕自己又像上一年一样,一停就一年多了. 想好好学习数据库(SQL SERVER)方面的 ...

  3. 【LCA】bzoj 2144:跳跳棋

    2144: 跳跳棋 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 248  Solved: 121[Submit][Status][Discuss] ...

  4. redhat_suse双系统引导

    先装suse11系统,再装redhat6后出现引导中suse系统无法启动解决方法:在redhat中将suse所在分区挂载出来,找其boot/grub/menu.lst下的启动项,将该启动项复制到red ...

  5. uva 10069

    简单的dp 但是一个大数加法  套用了末位大牛的类模板 #include <cstdio> #include <cstring> #include <algorithm& ...

  6. ibatis的there is no statement named xxx in this SqlMap

    报错情况如下: com.ibatis.sqlmap.client.SqlMapException: There is no statement named Control.insert-control ...

  7. 【Mysql进阶技巧(1)】 MySQL的多表关联与自连接

    自连接 测试数据准备 CREATE TABLE `t2` ( `id` int(11) NOT NULL, `gid` char(1) DEFAULT NULL, `col1` int(11) DEF ...

  8. 安装Ubuntu双系统系列——更换源

    Ubuntu 有一个非常有用的命令 apt-get,它可以帮助你下载软件,还可以安装,下载并安装的命令是 apt-get install. 那Ubuntu默认是从哪里下载软件呢,这可以查看文件/etc ...

  9. itoa函数的实现(不同进制)

    2013-07-08 17:12:30 itoa函数相对于atoi函数,比较简单,还是要注意考虑的全面. 小结: 一下几点需要考虑: 对负数,要加上负号: 考虑不同进制,根据要求进行处理:对不同的进制 ...

  10. CCS学习资料汇总

    2013-06-20 10:31:52 CSDN无网无痕的专栏,有比较多的关于DSP的文章: http://blog.csdn.net/zzsfqiuyigui/article/details/694 ...