1.read函数

调用read函数从文件去读数据,函数定义如下:
#include <unistd.h>
ssize_t read(int filedes, void* buff, size_t nbytes);

成功则返回实际读取的byte数,如果已经达到文件结尾则返回0,出错则返回-1.

2.write函数

调用write函数向打开的文件写入数据,函数定义如下:
#include <unistd.h>
ssize_t write(int filedes, void* buff, size_t nbytes);

成功则返回实际写入的byte数,出错则返回-1.

3.lseek函数

每个打开的文件都有一个关联的“当前偏移量”,用于记录从文件到当前当前位置的偏移字节数,lseek函数是设置这个当前偏移量

的函数,函数的声明如下:
#include <unistd.h>
off_t lseek(int filedes, off_t offset, int whence);

成功则返回新的文件偏移量,失败则返回-1.

如果whence是SEEK_SET,则文件的偏移量设置为文件开始加上offset个字节。
如果whence是SEEK_CUR,则文件的偏移量设置为当前偏移量开始加上offset个字节,offset可正可负。
如果whence是SEEK_END,则文件的偏移量设置为文件长度加上offset个字节,offset可正可负。

不是每个文件都能够设置偏移量,有些文件如管道,FIFO或socket,无法设置偏移量,可以使用如下函数测试是否可以设置偏移量,
如果返回-1,则表示不可以。
off_t currpos;
currpos = lseek(fd, 0, SEEK_CUR);

2.实践

创建一个文件,往文件中写入10个字符,然后再使用lseek定位文件开始加上4个字节的偏移量,然后读取接下来的内容。
#include <fcntl.h>
#include <stdio.h> int main(void){
int fd,byteNum,result;
char wbuf[10] = "123456789";
char rbuf[10];
if((fd = open("./a.txt", O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IXUSR))<0){
perror("open");
return -1;
} if((byteNum = write(fd, wbuf, 10))<0){
perror("write");
return -1;
} if((result = lseek(fd, 4, SEEK_SET))<0){
perror("lseek");
return -1;
} if((byteNum = read(fd, rbuf, 10)) < 0){
perror("read");
return -1;
} printf("read content:%s\n",rbuf); close(fd);
return 0;
}

运行结果:

read content:56789

如果将偏移量设置为文件开始加上一个负数,调用lseek就会出错。
#include <fcntl.h>
#include <stdio.h> int main(void){
int fd,byteNum,result;
char wbuf[10] = "123456789";
char rbuf[10];
if((fd = open("./a.txt", O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IXUSR))<0){
perror("open");
return -1;
} if((byteNum = write(fd, wbuf, 10))<0){
perror("write");
return -1;
} if((result = lseek(fd, -1, SEEK_SET))<0){
perror("lseek");
return -1;
} if((byteNum = read(fd, rbuf, 10)) < 0){
perror("read");
return -1;
} printf("read content:%s\n",rbuf); close(fd);
return 0;
}

运行结果:

lseek: Invalid argument

是不是offset就一定不能为负数呢,不一定,只要最终的偏移量不小于0就可以了,看下面的例子。
#include <fcntl.h>
#include <stdio.h> int main(void){
int fd,byteNum,result;
char wbuf[10] = "123456789";
char rbuf[10];
if((fd = open("./a.txt", O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IXUSR))<0){
perror("open");
return -1;
} if((byteNum = write(fd, wbuf, 10))<0){
perror("write");
return -1;
} if((result = lseek(fd, -4, SEEK_CUR))<0){
perror("lseek");
return -1;
} if((byteNum = read(fd, rbuf, 10)) < 0){
perror("read");
return -1;
} printf("read content:%s\n",rbuf); close(fd);
return 0;
}

运行结果:

read content:789
如果文件偏移量大于文件长度再写入数据,那么生成的文件就会出现空洞。先往文件写入10个字符,再跳过20个字符,再写入10个字符。
#include <fcntl.h>
#include <stdio.h> int main(void){
int fd,byteNum,result;
char wbuf[10] = "123456789";
char rbuf[10];
if((fd = open("./a.txt", O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR))<0){
perror("open");
return -1;
} if((byteNum = write(fd, wbuf, 10))<0){
perror("write");
return -1;
} if((result = lseek(fd, 40960, SEEK_END))<0){
perror("lseek");
return -1;
} if((byteNum = write(fd, wbuf, 10)) < 0){
perror("write");
return -1;
} close(fd);
return 0;
}

运行结果:

-rw------- 1 root root 40980 2013-09-09 15:03 a.txt
使用od命令查看文件内容:
root@virtual-machine:~# od -c a.txt
 

0000000   1   2   3   4   5   6   7   8   9  \0  \0  \0  \0  \0  \0  \0

0000020  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0

*

0120000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0   1   2   3   4   5   6

0120020   7   8   9  \0

0120024

 
空洞的内容全部置为0

查看下文件占用的磁盘大小:
8 -rw------- 1 root root 40980 2013-09-09 15:41 a.txt

文件虽然有40980个字节,只占用了8个block,即8K(这边的block不是文件系统的block,而是kernel block,linux中,
kernel block大小为1K),如果是没有空洞的文件,则占用磁盘大小应该是44K。可见,虽然有空洞,但是实际存储时没
有占用文件大小的磁盘空间。

《UNIX环境高级编程》笔记--read函数,write函数,lseek函数的更多相关文章

  1. UNIX环境高级编程笔记之文件I/O

    一.总结 在写之前,先唠几句,<UNIX环境高级编程>,简称APUE,这本书简直是本神书,像我这种小白,基本上每看完一章都是“哇”这种很吃惊的表情.其实大概三年前,那会大三,我就买了这本书 ...

  2. UNIX环境高级编程笔记之高级I/O

    本章说明了很多高级I/O功能: 非阻塞I/O——发一个I/O操作,不使其阻塞,记录锁,STREAMS机制 I/O多路转接——select和poll函数 readv和writev函数,以及存储映射I/O ...

  3. UNIX环境高级编程笔记 目录

    每一章的重点会使用加粗字体 第一章:UNIX基础知识:UNIX体系结构:文件和目录:输入和输出:程序和进程:出错处理:信号:时间值:系统调用和库函数 第三章:文件I/O:文件描述符:文件操作函数:文件 ...

  4. UNIX环境高级编程——存储映射I/O(mmap函数)

         共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共 ...

  5. UNIX环境高级编程笔记之进程控制

    本章重点介绍了进程控制的几个函数:fork.exec族._exit.wait和waitpid等,主要需要掌握的是父进程和子进程之间的运行机制,怎么处理进程的正常和异常终止.以及怎么让进程执行不同的程序 ...

  6. UNIX环境高级编程笔记之标准I/O库

    一.总结 文件I/O一章讲了不带缓冲的I/O,本章讲的是带缓冲的I/O.不带缓冲针对的是内核的系统调用,而带缓冲针对的是用户空间的标准库函数,是基于带缓冲的I/O实现的.不带缓冲的I/O通过文件描述符 ...

  7. UNIX环境高级编程笔记之线程

    本章涉及到线程的一些基本知识点,讨论了现有的创建线程和销毁线程的POSIX.1原语,此外,重点介绍了线程同步问题,讨论了三种基本的同步机制:互斥量.读写锁.条件变量.

  8. UNIX环境高级编程笔记之进程环境

    本章讲的都是一些非常基础的知识,目的是为了下一章讲进程控制做铺垫,所以,本章就不做过多的总结了,直接看图吧.

  9. unix环境高级编程一书中部分错误处理函数

    #include <unistd.h> #include <errno.h> #include <string.h> #include <stdio.h> ...

  10. UNIX环境高级编程——线程属性

    pthread_attr_t 的缺省属性值 属性 值 结果 scope PTHREAD_SCOPE_PROCESS 新线程与进程中的其他线程发生竞争. detachstate PTHREAD_CREA ...

随机推荐

  1. nginx学习六 高级数据结构之双向链表ngx_queue_t

    1 ngx_queue_t简单介绍 ngx_queue_t是nginx提供的一个轻量级的双向链表容器,它不负责存储数据,既不提供数据的内存分配.它仅仅有两个指针负责把数据链入链表.它跟stl提供的qu ...

  2. DataTable的属性与使用方式

    一.DataTable简介 (1)构造函数            DataTable()   不带参数初始化DataTable 类的新实例.            DataTable(string t ...

  3. Delphi_MemoryModule — load DLL from memory. Also includes hooking utilities.

    https://github.com/Fr0sT-Brutal/Delphi_MemoryModule

  4. python爬虫实战2百度贴吧爬html

    转自:http://blog.csdn.net/wxg694175346/article/details/8927832 import string, urllib2 #定义百度函数 def baid ...

  5. c# winform 弹出确认消息框判断是否删除?

    if (MessageBox.Show("确认删除?", "此删除不可恢复", MessageBoxButtons.YesNo) == DialogResult ...

  6. linux学习过程中所需要看的一些书籍

    入门类 一直认为,在一个系统上学习开发之前,首先需要熟悉这个系统的使用.鉴于天朝的国情,绝大部分人第一个接触的操作系统就是Windows,因此对于这绝大部分人来说,如果要学习Linux开发,学会使用这 ...

  7. Chrome 快捷键

    chrome窗口和标签页快捷键: Ctrl+N 打开新窗口 Ctrl+T 打开新标签页 Ctrl+Shift+N 在隐身模式下打开新窗口 Ctrl+O,然后选择文件 在谷歌浏览器中打开计算机上的文件 ...

  8. java--进步学习IO

    import java.io.*; public class Demo1 { public static void main(String []args) throws Exception{ File ...

  9. haproxy path_beg

    path_beg : prefix match 前缀匹配 path_dir : subdir match path_dom : domain match path_end : suffix match ...

  10. 浅尝key-value数据库(一)——一览NoSQL

    浅尝key-value数据库(一)——一览NoSQL 最近由于一个项目的关系,研究了一下key-value数据库这个最近很火的概念.本系列从项目需求的角度分析并测试了几个key-value数据库的性能 ...