c语言lng文件charset属性,C基础之-文件基础

文件基础

概念:

一组相关数据的有序集合

文件类型

不同操作系统支持的文件类型是不相同的,这里列出的是linux

常规文件  r

目录文件  d

字符设备文件  c

块设备文件  b

管道文件  p

套接字文件  s

符号链接文件  l

标准I/O

由ANSI C标准定义

主流操作系统上都实现了C库

特点: 标准I/O通过缓冲机制减少系统调用,实现更高的效率

FILE

标准IO用一个结构体类型来存放打开文件的相关信息

标准IO的所有操作都是围绕FILE来进行的

流(stream)

FILE又被称为流(stream)又被分为文本流、二进制流两种

windows:

二进制流:换行符 -- '\n'

文本流:换行符 -- '\r''\n'

linux

换行符:'\n'

流的缓冲类型

全缓冲:

当流的缓冲区无数据或空间时才执行实际I/O操作

行缓冲:

当在输入和输出中遇到换行符时,才执行I/O操作

当流和一个终端关联时,典型的行缓冲

无缓冲:

数据直接写入文件,流不进行缓冲

标准I/O预定的3个流,程序运行时自动打开

标准输入流

0

STDIN_FILENO

stdin

标准输出流

1

STDOUT_FILENO

stdout

标准错误流

2

STDERR_FILENO

stderr

流打开

FILE *fopen(const char * path,const char *mode)

成功时返回流指针;错误返回NULL

- 当用fopen新建文件后,该文件的权限为0666(rw-rw-rw-)

- 在linux系统中 umask设定会影响文件的权限访问 可以通过umask函数进行对应的修改

mode参数:

"r"或"rb"

以只读的方式打开文件,文件必须存在

"r+"或"r+b"

以读写的方式打开文件,文件必须存在

"w"或"wb"

以只写的方式打开文件,若文件存在则文件长度清零。若文件不存在则创建

"w+"或"w+b"

以只写方式打开文件,其他同"w"

"a"或"ab"

以只写的方式打开文件,若文件不存在则创建;向文件写入的数据将被追加到文件末尾

"a+"或"a+b"

以读写的方式打开文件。其他同"a"

*当给"b"参数时候,表示以二进制方式打开文件,但Linux下忽略该参数

错误流处理

void perror(const char *)

输入提示关键字 捕获当前错误并加输入的关键字返回

打印错误信息 例如

intmain() {

FILE*fp;if ((fp = fopen("test","r+"))==NULL){

perror("fopen");return -1;

}

}//out//fopen: No such file or directory

#include #include //需要引入

#include //需要引入 标准错误输入

intmain() {

FILE*fp;if ((fp = fopen("test","r+"))==NULL){

printf("fopen:%s",strerror(errno));return -1;

}

}

判断是否出错或结束

#include

int ferror(FILE *stream);int feof(FILE *stream);//ferror()返回1表示流出错;否则返回0//feof()返回1表示已经到末尾,否则返回0

读写流

流支持不同的读写方式

读写一个字符:

//fgetc()/fputc() 一次读/写一个字符

输入

#include

int fgetc(FILE *stream);int getc(FILE *stream);int getchar(void);//成功时返回读取的字符//若到文件的末尾或出错返回EOF

Demo:

#include

intmain() {intch;

ch= fgetc(stdin); //从标准输入获取

printf("%c", ch);

}

#include

intmain() {

FILE*fp;int ch = 0;int i = 0;int count = 0;if ((fp = fopen("./a.out", "r")) ==NULL) {

perror("fopen");return -1;

}while ((ch = fgetc(fp)) !=EOF) {

count++;

}

printf("文本长度 :%d", count);

}

输出

#include

int fputc(int c,FILE *stream);int putc(int c,FILE *stream);int putchar(intc);//成功时返回写入的字符//出错时返回EOF

Demo:

#include

intmain() {

putc('a',stdout);

putchar('\n');

}//out//a//

#include

intmain() {

FILE*fp;int ch = 0;if ((fp = fopen("./a.out", "w")) ==NULL) {

perror("fopen");return -1;

}for (ch = 'a'; ch <= 'z', ch++;) {

fputc(ch,fp);//输出到文本

}

}

文件copy

#include

int main(int argc, char *argv[]) {

FILE*src, *desc;inti;if (argc < 3) {

puts("Few parameters:project : ");return -1;

}//打开目标文件

if ((src = fopen(argv[1], "r")) ==NULL) {

perror("src:");return -1;

}if ((desc = fopen(argv[2], "w")) ==NULL) {

perror("desc:");

fclose(src);//失败释放打开的句柄

return -1;

}while ((i = fgetc(src)) !=EOF) {

fputc(i, desc);

}

fclose(src);

fclose(desc);

}

读写一行:

//fgets()/fputs() 一次读/写一行

输入

#include

char *gets(char *s);char *fgets(char *s,int size,FILE *stream);//成功时返回s,到文件末尾或出错时返回NULL//gets不推荐使用,容易造成缓冲区溢出;//***遇到'\n'或已输入size-1个字符返回时,总是包含'\0'

输出

#include

int puts(const char *s);int fputs(const char *s,FILE *stream);//成功时返回输出的字符个数//出错返回EOF//puts将缓冲区s中的字符串输出到stdout,并追加'\n'

demo:

#include

int main(int argc, char *argv[]) {

FILE*fp;char buf[] = "hello world";if ((fp = fopen(argv[1], "a")) ==NULL) {

perror("fopen");return -1;

}

fputs(buf, fp);

}

读写若干个对象:

//fread()/fwrite() 每次读/写若干个对象,而每个对象具有相同的长度

#include size_t fread(void *ptr,size_t size,size_t n,FILE *fp); //容器指针,存储元素的长度,读取的长度,文件句柄

size_t fwrite(const void *prt,size_t size,size_t n,FILE *fp);//成功返回读写的对象个数//出错返回EOF

demo

#include

int main(int argc, char *argv[]) {

FILE*fp;int buf[10] ={};if ((fp = fopen(argv[1], "a")) ==NULL) {

perror("fopen");return -1;

}if (fread(buf, sizeof(int), 10, fp) < 0) {

perror("fread");return -1;

}

}

copy文件

#include

#define N 1024

int main(int argc, char *argv[]) {

FILE*src, *desc;int i[N] ={};int n = 0;if (argc < 3) {

puts("Few parameters:project : ");return -1;

}//打开目标文件

if ((src = fopen(argv[1], "r")) ==NULL) {

perror("src:");return -1;

}if ((desc = fopen(argv[2], "w")) ==NULL) {

perror("desc:");

fclose(src);//失败释放打开的句柄

return -1;

}if ((n = fread(i, sizeof(int), N, src)) > 0) {

fwrite(i, n,sizeof(int), desc);

}

fclose(src);

fclose(desc);

}

刷新流

fflush()

#include

int fflush(FILE *fp);//成功时返回0//出错返回EOF

刷新会将缓冲区的内容落盘

定位流

ftell/fseek/rewind

#include

long ftell(FILE *stream);long fseek(FILE *stram,long offset,int whence); //offset表示偏移量 可正可负 whence表示基准点

void rewind(FILE *stram);//ftell()成功时返回流的当前读写位置,错误时返回EOF//fseek()定位一个流,成功时返回0,出错时返回EOF//whence参数:SEEK_SET-文件开头/SEEK_CUR-当前位置/SEEK_END-文件结尾//rewind将流定位到起始位置//读写流时,当前读写位置自动后移

Demo:

在文件末尾增加字符't'

#include

int main(int argc, char *argv[]) {

FILE*fp;//打开目标文件

if ((fp = fopen(argv[1], "r")) ==NULL) {

perror("src:");return -1;

}//移动到文章末尾

fseek(fp, 0, SEEK_END);//增加字符t

fputc('t', fp);

fclose(fp);

}

获取文件长度

#include

int main(int argc, char *argv[]) {

FILE*fp;inti;//打开目标文件

if ((fp = fopen(argv[1], "r")) ==NULL) {

perror("src:");return -1;

}//移动到文章末尾

fseek(fp, 0, SEEK_END);//获取文件长度

i =ftell(fp);

printf("长度为%d",i);

fclose(fp);

}

格式化输出

#include

int printf(const char *fmt,...);int fprintf(FILE *stream,const char *fmt,...)int sprintf(char *s,const char *fmt,...)//成功时返回输出的字符个数//出错时返回EOF

#include

int main(int argc, char *argv[]) {

FILE*fp;intyear, month, day;char buf[64];//打开目标文件

if ((fp = fopen(argv[1], "r")) ==NULL) {

perror("src:");return -1;

}

year= 2020;

month= 05;

day= 05;//输入到fp的流中

fprintf(fp, "%d-%d-%d", year, month, day);//输入到缓冲区中

sprintf(buf, "%d-%d-%d", year, month, day);

}

关闭流

int fclose(FILE *stream);

调用成功返回0,失败返回EOF,并设置errno

流成功关闭后会自动刷新缓冲中的数据并释放缓冲区

当一个程序正常终止时,所有打开的流都会被关闭

流一旦关闭将不能对其执行任何操作

在linux中打开流的最大个数(修改ulimit可更改)

1021 + stdin + stdout + stderr = 1024

文件I/O

POSIX(可移植操作系统接口)定义的一组函数

不提供缓冲机制,每次读写操作都引起系统调用

核心概念是文件描述符

可以访问各种类型文件

在Linux下,标准IO基于文件IO实现

文件描述符

每一个打开的文件都对应一个文件描述符

文件描述符是一个非负整数。Linux为程序中每打开的问你件分配一个文件描述符

文件描述符从0开始分配,一次递增

文件IO操作通过文件描述符来完成

文件描述符的0,1,2的含义

分别是标准输入,标准输出,标准错误 一一对应

打开文件、创建文件

#include

int open(const char *path,intoflag,mode_t mode);//path文件路径//oflag打开方式,可以是多个参数//当open成功时返回文件描述符//出错返回EOF//创建文件时第三个参数指定文件的权限//设备文件只能打开不能创建

O_RDONLY 以只读方式打开文件

O_WRONLY 以只写方式打开文件

O_RDWR 以可读写方式打开文件. 上述三种旗标是互斥的, 也就是不可同时使用, 但可与下列的旗标利用OR(|)运算符组合.

O_CREAT 若欲打开的文件不存在则自动建立该文件.

O_EXCL 如果O_CREAT 也被设置, 此指令会去检查文件是否存在. 文件若不存在则建立该文件, 否则将导致打开文件错误. 此外, 若O_CREAT 与O_EXCL 同时设置, 并且欲打开的文件为符号连接, 则会打开文件失败.

O_NOCTTY 如果欲打开的文件为终端机设备时, 则不会将该终端机当成进程控制终端机.

O_TRUNC 若文件存在并且以可写的方式打开时, 此旗标会令文件长度清为0, 而原来存于该文件的资料也会消失.

O_APPEND 当读写文件时会从文件尾开始移动, 也就是所写入的数据会以附加的方式加入到文件后面.

O_NONBLOCK 以不可阻断的方式打开文件, 也就是无论有无数据读取或等待, 都会立即返回进程之中.

O_NDELAY 同O_NONBLOCK.

O_SYNC 以同步的方式打开文件.

O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接, 则会令打开文件失败.

O_DIRECTORY 如果参数pathname 所指的文件并非为一目录, 则会令打开文件失败。注:此为Linux2. 2 以后特有的旗标, 以避免一些系统安全问题.

参数mode 则有下列数种组合, 只有在建立新文件时才会生效, 此外真正建文件时的权限会受到umask 值所影响, 因此该文件权限应该为 (mode-umaks).

S_IRWXU00700 权限, 代表该文件所有者具有可读、可写及可执行的权限.

S_IRUSR 或S_IREAD, 00400 权限, 代表该文件所有者具有可读取的权限.

S_IWUSR 或S_IWRITE, 00200 权限, 代表该文件所有者具有可写入的权限.

S_IXUSR 或S_IEXEC, 00100 权限, 代表该文件所有者具有可执行的权限.

S_IRWXG 00070 权限, 代表该文件用户组具有可读、可写及可执行的权限.

S_IRGRP 00040 权限, 代表该文件用户组具有可读的权限.

S_IWGRP 00020 权限, 代表该文件用户组具有可写入的权限.

S_IXGRP 00010 权限, 代表该文件用户组具有可执行的权限.

S_IRWXO 00007 权限, 代表其他用户具有可读、可写及可执行的权限.

S_IROTH 00004 权限, 代表其他用户具有可读的权限

S_IWOTH 00002 权限, 代表其他用户具有可写入的权限.

S_IXOTH 00001 权限, 代表其他用户具有可执行的权限.

Demo:

#include #include

//以只写的方式打开文件,如果不存在则创建,如果存在则清空

int main(int argc, char *argv[]) {intfd;if ((fd = open("1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {

perror("open");

}

}

#include #include#include //需要引入

#include //需要引入 标准错误输入//以读写的方式打开文件,如果不存在则创建,如果存在则报错

int main(int argc, char *argv[]) {intfd;if ((fd = open("1.txt", O_RDWR | O_CREAT, 0666)) < 0) {if (errno ==EEXIST) {

perror("exist error");

}else{

perror("other error");

}

}

}

读取文件

#include ssize_t read(int fd,void *buf,size_t count); //buf容器 count 一般定为缓冲区的大小 保证缓冲区不会溢出//成功返回实际读取的字节数//失败返回EOF//读到文件尾时返回0

demo:统计文件大小

#include #include#include

int main(int argc, char *argv[]) {intfd, n, total;char buf[64];if ((fd = open(argv[1], O_RDONLY)) < 0) {

perror("open");return -1;

}//读取文件的内容//获取文件大小

while ((n = read(fd, buf, 64)) > 0) {

total+=n;

}

}

写入文件

#include ssize_t write(int fd,void *buf,size_t count);//成功时返回实际写入的字节数//出错返回EOF//count不应超过buf大小

demo:键盘输入

#include #include#include#include

int main(int argc, char *argv[]) {intfd;char buf[64];if ((fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {

perror("open");return -1;

}//读取文件的内容//获取文件大小

while (fgets(buf, 20, stdin) > 0) {if (strcmp(buf, "quit\n") == 0) {break;

}

write(fd, buf, strlen(buf));

}

}

demo:文件的复制

#include #include#include

#define N 64

int main(int argc, char *argv[]) {intsrc, desc;intn;charbuf[N];if (argc < 3) {

perror("Parameter less than 3");return -1;

}//打开源文件 只读

if ((src = open(argv[1], O_RDONLY)) < 0) {

perror("open src");return -1;

}//打开目标文件

if ((desc = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {

perror("open desc");

close(src);return -1;

}//获取文件大小

while ((n = read(src, buf, N)) > 0) {

write(desc, buf, n);

}

close(src);

close(desc);

}

定位

#include off_t lseek(int fd,off_t offset,int whence); //与fseek类似 whence基准点一样//成功返回当前文件的读写位置//出错返回EOF

文件关闭

#include

int close(intfd);//成功时返回0//出错时返回EOF//程序结束时自动关闭所有打开的文件//文件关闭后,就不能对文件描述符进行操作

访问(打开)目录

#include DIR*opendir(const char*name); //name目录路径//DIR是用来描述一个打开的目录文件的结构体类型//成功时返回目录流指针//错误时返回NULL

查看目录内容

#include

struct dirent *readdir(DIR *dirp);//struct dirent是用来描述目录流中一个目录项的结构体类型//包含成员 char d_name[256] —— 文件名 其他参考帮助文档//成功时返回目录流dirp中下一个目录项//出错或到末尾是返回NULL

demo:查看指定目录下的文件名

#include #include

int main(int argc, char *argv[]) {

DIR*dirp;struct dirent *dp;if (argc < 2) {

perror("Parameter is less than 2");return -1;

}//打开目录

if ((dirp = opendir(argv[1])) ==NULL) {

perror("opendir");return -1;

}while ((dp = readdir(dirp)) !=NULL) {

printf("%s\n", dp->d_name);

}

closedir(dirp);

}

关闭目录流

#include

int closedir(DIR *dirp);//成功返回0//失败返回-1

修改文件的访问权限 chmod/fchmod

#include

int chomd(const char *path,mode_t mode);int fchmod(intfd,mode_t mode);//mode 例如 0666 权限码//成功时返回0//出错返回EOF//root用户和所有者才可以修改文件的访问权限//demo:

chomd("text.txt",0666);

获取文件的属性

#include

int stat(const char *path,struct stat *buf); //path为路径,buf为获取存放的结构体

int lstat(const char *path,struct stat *buf);int fstat(int fd,struct stat*buf);//stat与lstat区别: 如果path是符号链接stat获取到的是目标文件的属性,而lstat获取的是链接文件的属性//成功时返回0//出错返回EOF

//struct stat结构体属性//mode_t st_mode 文件类型和访问权限//uid_t st_uid 所有者id//uid_t st_gid 用户组id//off_t st_size 文件大小//time_t st_mtime 最后修改时间//....

mode_t st_mode  判断文件类型

//通过系统提供的宏来判断文件类型

st_mode & 0170000S_ISREG(st_mode)0100000S_ISDIR(st_mode)0040000S_ISCHR(st_mode)0020000S_ISBLK(st_mode)0060000S_ISFIFO(st_mode)0010000S_ISLNG(st_mode)0120000S_ISSOCK(st_mode)0140000

mode_t st_mode 获取权限

//通过系统提供的宏来获取we年访问权限//所有者

S_IRUSR——00400——8可读

S_IWUSR——00200——7可写

S_IXUSR——00100——6

//同组用户

S_IRGRP——00040——5S_IWGRP——00020——4S_IXGRP——00010——3

//其他组用户

S_IROTH——00004——2S_IWOTH——00002——1S_IXOTH——00001——0

//通过系统提供的宏来获取文件的访问权限//所有者

S_IRUSR——00400——8可读

S_IWUSR——00200——7可写

S_IXUSR——00100——6

//同组用户

S_IRGRP——00040——5S_IWGRP——00020——4S_IXGRP——00010——3

//其他组用户

S_IROTH——00004——2S_IWOTH——00002——1S_IXOTH——00001——0

来源:https://www.cnblogs.com/binHome/p/12840514.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值