Man 2 read 查询read的函数,如果提示找不到,需要安装man的文件
sudo yum install man-pages
1、perror函数打印报错信息;
#include
#include
void perror(const char* s);
perror("open file failed"); // perror函数用与打印报错信息到控制台,并且带上错误原因。
错误原因按照错误变量errno的值来决定 // 是一个枚举值 open file failde: No such file or directory
2、read函数在普通文件和设备文件的阻塞性不同
阻塞和不阻塞不是read的函数属性,而是文件的属性。
设备文件:/dev/tty 标准的输入STDIN_FILENO;
SOCKET 和 pipe这两种文件也是堵塞的。
#include
#include // 依赖以上两个头文件
off_t lseek(int fd, off_t offset, int whence);
fd 表示要 *** 作的文件描述符
offset是相对于whence(基准)的偏移量
whence 可以是SEEK_SET(文件指针开始),SEEK_CUR(文件指针当前位置) ,SEEK_END为文件指针尾
返回值:文件读写指针距文件开头的字节大小,出错,返回-1
lseek 主要作用是移动文件读写指针,因此还有两个作用:拓展文件和获取文件大小
#include
#include
#include
#include
#include
#include
void main() {
int fd=open("test.txt",O_RDWR);
if(fd == -1) {
perror("open test.txt");
exit(-1);
}
printf("file len:%d \n",lseek(fd,0,SEEK_END));
close(fd);
}
// lseek(fd,100,SEEK_SET));
// wirte(fd, "H", 1); //移动到距离文件开始的100个字节的位置 无论原来源文件大小,实现文件的拓展到101字节。
// offset 可以为负值,返回的文件大小与ls -ltr看到的是同一个结果
4、stat函数应用与stat_mode属性
stat和lstat都是获取文件属性
#include
#include
int stat(const char* filename, struct sat* buff);
// 通过文件名称filename获取文件信息,并报错到结构体buff中
struct stat buf;
stat("/etc/hosts", &buf);
printf("/etc/hosts file size = %d\n", buf.st_size);
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
stat_mode定义了以下多种情况:
S_IFMT 0170000 文件类型的位遮罩
S_IFSOCK 0140000 scoket
S_IFLNK 0120000 符号连接
S_IFREG 0100000 一般文件
S_IFBLK 0060000 区块装置
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符装置
S_IFIFO 0010000 先进先出
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限
上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode) 判断是否为符号连接
S_ISREG (st_mode) 是否为一般文件
S_ISDIR (st_mode) 是否为目录
S_ISCHR (st_mode) 是否为字符装置文件
S_ISBLK (s3e) 是否为先进先出
S_ISSOCK (st_mode) 是否为socket
stat_mode属性:文件的类型和存储的权限。
stat(pathName, &sb);
if((sb.st_mode & S_IFMT) == S_IFREG){
// 普通文件
} else (sb.st_mode & S_IFMT) == S_IFDIR){
// 目录文件
} else(S_IFLINK(sb.st_mode)) {
// 链接文件
}
// 判断文件权限
if(sb.st_mode & S_IROTH){
//可读权限
} else if(sb.st_mode & S_IROTH){
//可读权限
} else if(sb.st_mode & S_IROTH) {
// 可写权限
} else if(sb.st_mode & S_IROTH) {
// 可执行权限
}
5、lstat函数的使用
针对软连接文件而言,lstat函数可以穿透,指向的是本身的文件,而stat函数标识的是指向的文件属性。
DIR * pDir = opendir("dir"); // 打开目录
while((p=readdir(pDir) != NULL)) // 循环遍历函数
closedir(pDir); //关闭目录;
linux的目录遍历函数:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
void listDir(char *path)
{
DIR *pDir ;
struct dirent *ent ;
int i=0 ;
char childpath[512];
pDir=opendir(path);
memset(childpath,0,sizeof(childpath));
while((ent=readdir(pDir))!=NULL)
{
if(ent->d_type & DT_DIR)
{
if(strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
continue;
sprintf(childpath,"%s/%s",path,ent->d_name);
printf("path:%s/n",childpath);
listDir(childpath);
}
else
{
cout<d_name<
7、dup函数与dup2函数
在linux下,一切皆文件。
当文件被打开时,会返回文件描述符用于 *** 作该文件,从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2);)0表示标准输入,1表示标准输出,2表示标准错误。
一个进程当前有哪些打开的文件描述符可以通过/proc/进程ID/fd目录查看。
用于复制文件描述符的函数dup和dup2
dup2函数还具有文件重定向的功能。
dup2(fd, STDOUT_FILENO); // 修改了默认的printf的输出路径为fd打开的文件
#include
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup函数返回当前系统可用的最小整数值。
dup2函数返回第一个不小于newfd的整数值。
也就是分为两种情况:
①、如果newfd已经打开,则先将其关闭,再复制文件描述符。
②、如果newfd等于oldfd,则dup2返回newfd, 而不关闭它。
//测试dup2函数
#include
#include
#include
#include
#include
#include
#include
int main()
{
int fd = open("b.txt", O_RDWR | O_CREAT);
if(fd == -1)
{
perror("open");
exit(1);
}
int fd1 = open("a.txt", O_RDWR);
if(fd1 == -1)
{
perror("open");
exit(1);
}
printf("fd = %d\n", fd);
printf("fd1 = %d\n", fd1);
int ret = dup2(fd, fd1); //让fd1和fd同时指向b.txt
if(ret == -1)
{
perror("dup2");
exit(1);
}
printf("current fd = %d\n", ret);
char* buf = "hello ";
char* buf1 = " world!";
write(fd, buf, strlen(buf));
write(fd1, buf1 , strlen(buf1));
close(fd);
close(fd1);
return 0;
8、fcntl函数
fcntl函数用于对已经打开的文件描述符进行各种控制 *** 作以及改变已打开文件的各种属性。
#include
#include
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd ,struct flock* lock);
(1)F_DUPFD
与dup函数功能一样,复制由fd指向的文件描述符,调用成功后返回新的文件描述符,与旧的文件描述符共同指向同一个文件。
(2)F_GETFD
读取文件描述符close-on-exec标志
(3)F_SETFD
将文件描述符close-on-exec标志设置为第三个参数arg的最后一位
(4)F_GETFL
获取文件打开方式的标志,标志值含义与open调用一致
(5)F_SETF
设置文件打开方式为arg指定方式
文件记录锁是fcntl函数的主要功能。
记录锁:实现只锁文件的某个部分,并且可以灵活的选择是阻塞方式还是立刻返回方式
当fcntl用于管理文件记录锁的 *** 作时,第三个参数指向一个struct flock *lock的结构体
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)