io编程linux,Linux+C学习笔记之IO编程

1. linux中的文件类型

a.任何设备在Linux中都是文件

b.普通文件(regular file) [-]

纯文本文件(ASCII)

二进制文件(binary)

数据格式的文件(data) /var/log/wtmp (cat last)

c.目录文件(directory) [d]

d.连接文件(link) 快捷方式 [l]

e.设备与设备文件(device) /dev

块设备文件(block) [b]

字符设备文件(character) [c]

套接字(sockets) /var/run [s]

f.管道(pipe,FIFO),先进先出,[p]

2.文件描述符

在linux系统中,所有打开的文件都对应一个文件描述符。文件描述符的本质是一个非负整数。当打开一个文件时,该整数由系统来分配。文件描述符的范围是0~OPEN_MAX。早期的UNIX版本OPEN_MAX=19,即允许每个进程同时打开20个文件,现在很多系统则将其增加到1024。

三个系统自定义的文件描述符:

#define STDIN_FILENO 0  //标准输入设备

#define STDOUT_FILENO 1 //标准输出设备

#define STDERR_FILENO 2 //标准错误输出设备

3.linux中文件编程可以使用两种方法:

linux系统调用

C语言库函数

4.linux系统调用函数

①int creat(const char *filename,mode_t mode)

filename:要创建的文件名(包含路径,缺省为当前路径)

mode:创建模式

常见创建模式:

S_IRUSR

可读

S_IWUSR

可写

S_IXUSR

可执行

S_IRWXU

可读、写、执行

注意:模式也可以用數字來表示,如:4(100)可以表示可读。

为什么将模式设为0777的话,结果文件权限是755?此时要知道umask(用户掩码)的知识,每个文件的最大权限只能是755(用0777和0022异或)。

②int open(const char *pathname, int flags)

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

pathname:要打开的文件名(包含路径,缺省为当前路径)

flags:打开标志

常见的打开标志:

O_RDONLY

只读方式打开

O_WRONLY

只写方式打开

O_RDWR

读写方式打开

O_APPEND

追加方式打开

O_CREAT

创建一个文件

O_NOBLOCK

非阻塞方式打开

注意:如果打开标志用到了O_CREAT,就要使用第二个函数打开文件,因为文件之前没有创建且没有权限。

③int close(int fd)

关闭指定的文件。

④ssize_t read(int fd, void *buf, size_t length)

功能: 从文件描述符fd所指定的文件中读取 length个字节到buf所指向的缓冲区中, 返回值为实际读取的字节数。

返回值:

成功:读到的字节数

已到达文件末尾:0

出错:-1

⑤ssize_t write(int fd, void *buf, size_t length)

功能: 把length个字节从buf指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为实际写入的字节数。

⑥off_t lseek(int fd, off_t offset, int whence)

功能: 将文件读写指针相对whence移动offset 个字节。操作成功时,返回文件指针相对于文件头的位置。

返回值:

成功:文件的当前偏移

已出错:-1

whence可使用下述值之一:

SEEK_SET:相对文件开头

SEEK_CUR:相对文件读写指针的当前位置

SEEK_END:相对文件末尾

offset可取负值,表示向前移动。例如下述调用可将文件指针相对当前位置向前移动5个字节:

lseek(fd, -5, SEEK_CUR);

如何利用lseek来计算文件长度?

lseek(fd,0,SEEK_END);

⑦有时我们需要判断文件是否可以进行某种操作(读,写等),这时可以使用access函数:

int access(const char*pathname,int mode)

pathname:文件名称

mode:要判断的访问权限。

可以取以下值或者是他们的组合。

R_OK:文件可读,

W_OK:文件可写,

X_OK:文件可执行,

F_OK:文件存在。

返回值:测试成功时,函数返回0,否则返回-1。

⑧fcntl函数解决文件共享问题,select函数用来处理IO复用的情况。

函数原型

int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exeptfds, struct timeval *timeout)

numfds:需要检查的号码最高的文件描述符加

readfds:由 select()监视的读文件描述符集合

writefds:由 select()监视的写文件描述符集合

exeptfds:由 select()监视的异常处理文件描述符集合

timeout:

NULL:永远等待,直到捕捉到信号或文件描述符已准备好为止

具体值:struct timeval 类型的指针,若等待为 timeout 时间还没有文件描符准备好,就立即返回

0:从不等待,测试所有指定的描述符并立即返回

struct timeval {

long tv_sec; /* second */

long tv_unsec; /* and microseconds*/

}该结构在头文件中已有定义

⑨DIR *opendir(const char *name);

功能:打开目录

⑩ struct dirent *readdir(DIR *dir);

功能:读取目录

11.获取文件属性

通过stat/fstat/lstat等函数获取文件相关属性。

int stat(const char *filename,struct stat *buf);/*通过文件名获取属性*/

int fstat(int fd,struct stat *buf);/*通过文件描述符获取属性*/

int lstat(const char *filename,struct stat *buf);/*类似stat,支持符号链接*/

返回值:

成功:0

失败:-1,并设置errno

12.在编写程序的时候,有时候需要得到当前路径。系统调用提供了getcwd函数来解决这个问题。

char *getcwd(char *buffer,size_t size)

我们提供一个size大小的buffer,getcwd 会把当前的路径名copy 到buffer中.如果 buffer太小,函数会返回-1。

13.int mkdir(char * dir, int mode)

功能:创建一个新目录。

返回值:0表示成功,-1表示出错。

14.时间类型 (#include )

Coordinated Universal Time(UTC):世界标准时间,也就是大家所熟知的格林威治标准时间(Greenwich Mean Time,GMT)。

Calendar Time:日历时间,是用“从一个标准时间点(如:1970年1月1日0点)到此时经过的秒数”来表示的时间。

获取日历时间:

time_t time(time_t *tloc)

功能:获取日历时间,即从1970年1月1日0 点到现在所经历的秒数。

/* typedef long time_t */

获取格林威治时间:

struct tm *gmtime(const time_t *timep)

功能:将日历时间转化为格林威治标准时间,并保存至TM结构。

获取本地时间:

struct tm *localtime(const time_t *timep)

功能:将日历时间转化为本地时间,并保存至TM结构。

时间结构体:

struct tm {

int tm_sec;

//秒值

int tm_min;

//分钟值

int tm_hour;

//小时值

int tm_mday;

//本月第几日

int tm_mon;

//本年第几月

int tm_year;

//tm_year + 1900 = 哪一年

int tm_wday;

//本周第几日

int tm_yday;

//本年第几日

int tm_isdst;

//日光节约时间

};

时间的格式化输出:

char *asctime(const struct tm *tm)

功能:将tm格式的时间转化为字符串,如:

Sat Jul 30 08:43:03 2010

char *ctime(const time_t *timep)

功能:将日历时间转化为本地时间的字符串形式。

size_t strftime(char *s, size_t max, const char *format,const struct tm *tm);

功能:将tm格式的时间转化为指定格式的字符串

15.struct passwd *getpwuid(uid_t uid)

功能:获取用户ID等信息。

16.struct group *getgrgid(gid_t gid)

功能:获取同组用户ID等信息。

5.库函数(标准I/O)

①FILE *fopen(const char *filename, const char *mode)

filename:打开的文件名(包含路径,缺省为当前路径)

mode:打开模式

常见打开模式:

r, rb

只读方式打开(‘b’是针对二进制文件的,linux中可以不加)

w, wb

只写方式打开,如果文件不存在,则创建该文件 v a, ab追加方式打开,如果文件不存 在,则创建该文件 v r+, r+b, rb+读写方式打开

w+, w+b, wh+读写方式打开,如果文件不存在,则创建该文件

a+, a+b, ab+读和追加方式打开。如果文件不存在,则创建该文件

②size_t fread(void *ptr,size_t size, size_t n, FILE *stream)

功能: 从stream指向的文件中读取n个记录,每个记录的大小为size个字节,并将读取的数据放入ptr所指向的缓冲区,返回实际读取的记录数目。

③size_t fwrite(const void *ptr, size_t size, size_t n,FILE *stream)

功能: 从缓冲区ptr所指的数组中把n个记录写到stream指向的文件中,每个记录大小为size个字节,返回实际写入的记录数目。

④int fscanf(FILE *stream, char *format[,argument...])

功能:从一个流中进行格式化输入

⑤int fprintf(FILE *stream, char* format[,arg,...])

功能:格式化输出到一个流中

⑥int fseek(FILE *stream, long offset, int whence)

功能:定位

whence :

SEEK_SET 从文件的开始处开始搜索

SEEK_CUR 从当前位置开始搜索

SEEK_END 从文件的结束处开始搜索

6.六种COPY方式

①read/write

#include

#include

#include

#include

#include

int main(){

int fd1=open("c.txt",O_RDONLY);//以只读的方式打开c.txt

//判断是否打开成功

if(fd1!=-1){

printf("open file success~\n");

}else{

perror("open file failure~");

}

int fd2=open("b.txt",O_WRONLY);//以只写的方式打开b.txt

if(fd2!=-1){

printf("open file success~\n");

}else{

perror("open file failure~");

}

int buf[10]={'\0'};//一次读多少内容

int read_bytes=0;//表示每次读到的字节数

//循环读写

while(1){

read_bytes=read(fd1,buf,sizeof(buf));

if(read_bytes<=0)break;

write(fd2,buf,read_bytes);

}

close(fd1);

close(fd2);

return 0;

}

②fread/fwrite

#include

#include

int main() {

FILE* fp1 = fopen("copy2.c", "r");

FILE* fp2 = fopen("d.txt", "w+");

if (fp1 == NULL || fp2 == NULL) {

perror("fopen failure");

return -1;

}

char buf[8] = { '\0' };

int bytes = 0;

while (1) {

bytes = fread(buf, sizeof(char), sizeof(buf), fp1);

if (bytes <= 0)

break;

fwrite(buf, sizeof(char), bytes, fp2);

}

//③fgetc fputc(一个字节一个字节的读写)

/*while(1){

int ch=getchar();//fgetc(fp1);

if(ch==EOF)break;

//fputc(ch,fp2);

putchar(ch);//fputc(ch,stdout);

}

*/

//④fgets fputs(一行一行的读写)

/*char buf[32]={'\0'};

while(fgets(buf,sizeof(buf),fp1)!=NULL)

fputs(buf,fp2);

*/

//⑤fscanf fprintf

/*while (1) {

char buf[256] = { '\0' };

int ret = fscanf(fp1, "%s", buf);

if(ret==EOF)break;

fprintf(fp2, "%s", buf);

}

*/

//⑥system

/*system("cp copy.c a.txt");*/

//⑦使用execl协议族中的函数

/*

char *argv[] = { "cp", "copy.c","copy.txt", NULL };

execv("/bin/cp",argv);

*/

fclose(fp1);

fclose(fp2);

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值