C——文件I/O

C笔记——文件I/O(APUE)

库函数
1,字符串读写字符
fgets():原型char *fgets(char *s,int n,FILE stream),从stream流中读取1-n的字符串,遇EOF或换行符结束
fputs():原型int fputs(char *s,FILE *stream)文件流

fopen():打开文件 fclose():关闭文件

2,数据块读取函数
fread(buffer,size,count,fp) 读数据块如结构体或数组,buffer指读取文件的首地址,size为其大小,count是读取次数,fp地址指针
fwriter(buffer,size,count,fp) 写入文件块

#include <stdio.h> //printf在该头文件中声明
#include <unistd.h> //STDOUT_FILENO, stdout等在该头文件中声明
#include <string.h> //strlen在该头文件中声明,具体参考man strlen
#define MSG_STR “Hello World\n”
int main(int main, char *argv[])
{
printf("%s", MSG_STR);
fputs(MSG_STR, stdout);//stdout指标准输出流
write(STDOUT_FILENO, MSG_STR, strlen(MSG_STR));//STDOUT_FILENO文件描述符。0标准输入,1标准输出,2标准出错
return 0;
}
结果:
Hello World
Hello World
Hello World

系统调用
3,open() close() create() writer() read()函数详解

(1)create()系统调用
int creat(const char *path, mode_t mode);
此函数用来创建一个新文件并返回其fd。它等价于 open(path, O_WRONLY|O_CREAT|O_TRUNC, mode);

eg:
int fd;
fd=creat(“text.txt”, 0644);

(2)open()系统调用
int open(const char *path,int oflag,/mode_t mode/):用来打开文件,并返回文件描述符

(3)int close(int fd):用来关闭文件并返回文件描述符

(4) ssize_t write(int fd,const void *buf,size_t nbytes) 向fd 指向的文件写入buf指向的数据,大小不超过nbytes

(5)ssize_t read(int fd,void *buf,size_t nbytes)从fd指向的文件中提取buf中是数据,大小不超过nbytes

#include <unistd.h>

int close(int fd); 返回值:成功返回0,出错返回-1并设置errno
int open(const char *pathname,int oflag,mode);/*oflag指读取文件的状态,O_RDONLY只读 ,O_WRONLY 只写,O_RDWR读写,此三必须要有一个; 打开/创建文件时,至少得使用上述三个常量中的一个;mode只有在O_CREAT时有用。
以下常量是选用的:
O_APPEND 每次写操作都写入文件的末尾
O_CREAT 如果指定文件不存在,则创建这个文件,
mode的值 eg:664 6(user的权限:4+2:写执行)6(group的权限:4+2)4(leader)
【read4(读)write2(写) x1(执行)】
O_EXCL 与O_CREAT一起使用,open调用是一个原子操作。如果要创建的文件已存在,则返回 -1,并且修改 errno 的值
O_TRUNC 如果文件存在,并且以只写/读写方式打开,则清空文件全部内容
O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O
设置为非阻塞模式(nonblocking mode)
O_NDELAY 同O_NONBLOCK。

以下三个常量同样是选用的,它们用于同步输入输出

O_DSYNC 等待物理 I/O 结束后再 write。在不影响读取新写入的数据的前提下,不等待文件属性更新。
O_RSYNC read 等待所有写入同一区域的写操作完成后再进行
O_SYNC 等待物理 I/O 结束后再 write,包括更新文件属性的 I/O

**open 返回的文件描述符一定是最小的未被使用的描述符。
返回值:若所有欲核查的权限都通过了检查则返回 0 值,表示成功,只要有 一个权限被禁止则返回-1。

错误代码:
  EEXIST 参数 pathname 所指的文件已存在,却使用了 O_CREAT和 O_EXCL 旗标
  EACCESS 参数 pathname 所指的文件不符合所要求测试的权限。
  EROFS 欲测试写入权限的文件存在于只读文件系统内。
  EFAULT 参数 pathname 指针超出可存取内存空间。
  EINVAL 参数 mode 不正确。
  ENAMETOOLONG 参数 pathname 太长。
  ENOTDIR 参数 pathname 不是目录。
  ENOMEM 核心内存不足。
  ELOOP 参数 pathname 有过多符号连接问题。
  EIO I/O 存取错误。

1 #include <stdio.h>//使用printf()和perror()的
2 #include <errno.h>//参数errno
3 #include <string.h>//函数strerror()
4 #include <sys/types.h>//使用open()会使用的三个头文件
5 #include <sys/stat.h>
6 #include <fcntl.h>
7
8 #define BUFSIZE 1024
9 #define MSG_STR “Hello World\n”
10
11 int main(int argc, char *argv[])
12 {
13 int fd = -1;
14 int rv = -1;
15 char buf[BUFSIZE];
16
17 fd=open(“test.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);//O_RDWR读写 ,O_CREAT创建文件 ,O_TRUNC若文件存在且为只读或读写文件,则置为0
18 if(fd < 0)
19 {
20 perror(“Open/Create file test.txt failure”);//perror函数可以打印系统出错的原因,参数只能是一个字符串提示
21 return 0;
22 }
23 printf(“Open file returned file descriptor [%d]\n”, fd);//打印文件描述符,判断文件是否运行异(常使用文件printf来调试文件)
24
25 if( (rv=write(fd, MSG_STR, strlen(MSG_STR))) < 0 )//将MSG_STR即Hello World写入文件 strlen()函数用来计算字符串的长度 头文件:#include <string.h>
27 printf(“Write %d bytes into file failure: %s\n”, rv, strerror(errno));// strerror()用来依参数errno的错误代码来查询其错误原因的描述
28 goto cleanup;// goto 语句标号;执行goto语句后,程序将跳转到 语句标号: 处并执行其后的语句。
29 }
30
31 //memset(buf, 0, sizeof(buf));//void *memset(void *s,int c,size_t n),将已开辟内存空间 s 的首 n 个字节的值设为值 c
32 if( (rv=read(fd, buf, sizeof(buf))) < 0 )
33 {
34 printf(“Read data from file failure: %s\n”, strerror(errno));
35 goto cleanup;
36 }
37
38 printf(“Read %d bytes data from file: %s\n”, rv, buf);
39
40 cleanup:
41 close(fd);
42
return 0;//在其他任何函数调用return只会让本函数返回,而在main函数中会让main函数退出,因其实际调用了exit()函数

4.perror()和strerror()返回出错值
void perror(const char *s ):s为一段字符串,勿加入换行符,将输出到标准输出
char *strerror(int errno):将出错原因换成字符串,较常用

eg:
#include <stdio.h> //printf()和perror()在该头文件中声明
#include <errno.h> //errno系统全局变量在该头文件中声明
#include <string.h> //strerror()在该头文件中声明
#include <sys/types.h> //open()系统调用需要的三个头文件
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
char *file_name = “/test.txt”; //根目录下并不存在该文件,在open()打开时会失败
int fd=-1;

fd=open(file_name, O_RDONLY, 066);
if( fd < 0 )
{
perror(“Open file failure”);
printf(“Open file %s failure: %s\n”, file_name, strerror(errno));
return 0;
}
close(fd);
}

结果:Open file failure:No Such File
Open file/test.txt failure:No Such File

5.dup()和dup2()系统调用

int dup(int fd):返回的文件描述符一定是当前最小的
int dup2(int fd,int fd2):将一个新的文件描述符指向给fd,常用于标准输入输出和重定向

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>//使用dup()所需头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv)
{
int fd = -1;
fd = open(“std.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);
if(fd < 0)
{
printf(“Open file failure: %s\n”, strerror(errno));
return ;
}

dup2(fd, STDIN_FILENO); //标准输入重定向到 std.txt 文件中去
dup2(fd, STDOUT_FILENO); //标准输出重定向到 std.txt 文件中去
dup2(fd, STDERR_FILENO); //标准出错重定向到 std.txt 文件中去
printf(“fd=%d\n”, fd);

close(fd);
}

6.stat()和fsta():用来返回文件或目录相关的信息
int stat(const char*path,struct stat *buf)
int fstat(int fd,struct stat *buf)

struct stat {
dev_t st_dev; /* ID of device containing file /
ino_t st_ino; /
inode number /
mode_t st_mode; /
protection /
nlink_t st_nlink; /
number of hard links /
uid_t st_uid; /
user ID of owner /
gid_t st_gid; /
group ID of owner /
dev_t st_rdev; /
device ID (if special file) /
off_t st_size; /
total size, in bytes /
blksize_t st_blksize; /
blocksize for filesystem I/O /
blkcnt_t st_blocks; /
number of 512B blocks allocated /
time_t st_atime; /
time of last access /
time_t st_mtime; /
time of last modification /
time_t st_ctime; /
time of last status change */
};

eg:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main (int argc, char **argv)
{
struct stat stbuf;

stat(“stat.c”, &stbuf);
printf(“File Mode: %o Real Size: %luB, Space Size: %luB\n”, stbuf.st_mode, stbuf.st_size,
stbuf.st_blksize);

return 0;
}
zhulu@ubuntu-master:~/apue$ gcc stat.c
zhulu@ubuntu-master:~/apue$ ./a.out
File Mode: 100664 Real Size: 318B, , Space Size: 4096B

7.access():用来测试其权限位
int access(const char *path,int mode);
path:路径
mode有R_OK读许可权,W_OK写许可权,X_OK执行许可权,F_OK查看文件是否存在
eg:
#include <stdio.h>
#include <unistd.h>
#define TEST_FILE “access.c”
int main(void)
{
if( access(TEST_FILE, F_OK)!=0 )
{
printf(“File %s not exist!\n”, TEST_FILE);
return 0;
}
printf(“File %s exist!\n”, TEST_FILE);
if(access(TEST_FILE, R_OK)==0)
printf(“READ OK\n”);
if(access(TEST_FILE, W_OK)==0)
printf(“WRITE OK\n”);
if(access(TEST_FILE, X_OK)==0)
printf(“EXEC OK\n”);
return 0;
}

运行及结果:
zhulu@ubuntu-master:~/apue$ gcc access.c
zhulu@ubuntu-master:~/apue$ ./a.out
File access.c exist!
READ OK
WRITE OK

8.unlike() :可用来删除文件,其本质是让链接字数自减;关闭文件时,会先检查其进程个数如果为0,再检查链接个数,也为0的话则删除

9rename():文件重命名
int renmae(const char *newname,const char *oldnme)

10.linux下对文件的一些操作

int mkdir(const char *pathname,mode_t mode):创建文件
int rmdir(const char *path):删除文件
DIR opendir(const char *path):打开文件
struct dirent *readir(const char *path):读文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值