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;
}