linux编程——I/O操作之文件基本读写

open/close函数

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int close(int fd);

常用参数

O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写)
O_CREAT(若文件存在标志无用,若不存在就建新文件)需要知道创建文件权限一般是0644
O_TRUNC(若文件存在则长度被截为0(属性不变))
O_NONBLOCK(不阻塞)、O_APPEND()、O_EXCL
使用头文件: < fcntl.h>

open常见错误:

打开文件不存在
以写方式打开只读文件(打开文件没有对应权限)
以只写方式打开目录

最大打开文件数

一个进程默认打开文件的个数1024。
命令查看ulimit -a 查看open files 对应值。默认为1024
可以使用ulimit -n 4096 修改
当然也可以通过修改系统配置文件永久修改该值,但是不建议这样操作。
该命令在Ubuntu下成功 cat /proc/sys/fs/file-max可以查看该电脑最大可以打开的文件个数。受内存大小影响。

read/write函数

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
read与write函数原型类似。使用时需注意:read/write函数的第三个参数。
STDOUT_FILENO(屏幕输出FD)
练习:编写程序实现简单的cp功能。

程序比较:如果一个只读一个字节实现文件拷贝,使用read、write效率高,还是使用对应的标库函数效率高呢?

strace命令

shell中使用strace命令跟踪程序执行,查看调用的系统函数。

错误处理函数:

错误号:errno
perror函数: void perror(const char *s);
strerror函数: char *strerror(int errnum);

查看错误号:

/usr/include/asm-generic/errno-base.h
/usr/include/asm-generic/errno.h

总结read 函数返回值:

返回非零值: 实际read到的字节数
返回-1: 1):errno != EAGAIN (或!= EWOULDBLOCK) read出错

errno == EAGAIN (或== EWOULDBLOCK) 设置了非阻塞读,并且没有数据到达。
返回0:读到文件末尾

lseek函数

文件偏移
Linux中可使用系统函数lseek来修改文件偏移量(读写位置)
回忆fseek的作用及常用参数。 SEEK_SET、SEEK_CUR、SEEK_END

int lseek(FILE *stream, long offset, int whence); 成功返回0;失败返回-1
特别的:超出文件末尾位置返回0;往回超出文件头位置,返回-1

off_t lseek(int fd, off_t offset, int whence); 失败返回-1;成功:返回的值是较文件起始位置向后的偏移量。
特别的:lseek允许超过文件结尾设置偏移量,文件会因此被拓展。
注意文件“读”和“写”使用同一偏移位置。【lseek.c】

lseek常用应用:

使用lseek拓展文件:write操作才能实质性的拓展文件。单lseek是不能进行拓展的。

一般:write(fd, “a”, 1);
od -tcx filename 查看文件的16进制表示形式
od -tcd filename 查看文件的10进制表示形式

通过lseek获取文件的大小:lseek(fd, 0, SEEK_END); 【lseek_test.c】
【最后注意】:lseek函数返回的偏移量总是相对于文件头而言。

lseek常用应用:

使用lseek拓展文件:write操作才能实质性的拓展文件。单lseek是不能进行拓展的。
一般:write(fd, “a”, 1);

od -tcx filename 查看文件的16进制表示形式
od -tcd filename 查看文件的10进制表示形式
通过lseek获取文件的大小:lseek(fd, 0, SEEK_END); 【lseek_test.c】

【最后注意】:lseek函数返回的偏移量总是相对于文件头而言。

fcntl函数

改变一个【已经打开】的文件的 访问控制属性。
重点掌握两个参数的使用,F_GETFL 和 F_SETFL。 【fcntl.c】

ioctl函数

对设备的I/O通道进行管理,控制设备特性。(主要应用于设备驱动程序中)。通常用来获取文件的【物理特性】(该特性,不同文件类型所含有的值各不相同) 【ioctl.c】

/*************************************************************************
    > File Name: read.c
    > Author: 
    > Mail: 
    > Created Time: 2017年08月01日 星期二 20时15分41秒
 ************************************************************************/

#include
#include
#include
#include
#include
#include

#define MSG_WRITE "输出测试\n"

int main(void){
    //int fd = open("./text",O_RDWR); //打开文件  以读写方式
    //int wrfd = open("./text1",O_RDWR|O_CREAT,0644);
    int fd = open("/dev/tty",O_RDONLY);  //直接读取终端代码,以阻塞方式打开
    char buff[1024];
    int size = 0;
    printf("fd = %d,errno = %d\n",fd,errno); 

    size =  read(fd,buff,sizeof(buff));  //读取打开fd文件的内容 读取 buff大小的内容
    printf("size = %d\nbuff = %s\n",size,buff); 
    //write(wrfd,buff,strlen(buff));
    sleep(0.1);  //暂停0.1秒
    close(fd);   //关闭文件
    //close(wrfd);
    write(STDOUT_FILENO,MSG_WRITE,strlen(MSG_WRITE));  //打印在屏幕上
    return 0;
}

你可能感兴趣的:(linux编程)