1、可执行程序、shell命令
2、系统调用函数
3、库函数
4、查看特殊文件格式规范
#include
#include
int open(const char *pathname, int flags);
参1:打开文件的路径名
参2:打开文件的方式
O_RDONL|O_WRONLY|O_RDWR
成功返回一个新的文件描述符(整数)
失败返回-1
int open(const char *pathname, int flags, mode_t mode);
参3:打开文件的方式
O_RDONLY|O_WRONLY|O_RDWR #include<fcntl.h>
O_CREAT | O_NONBLOCK | O_APPEND | O_EXCL
使用前提是,参2 指定了O_CREAT.
传8进制数 ,用来描述文件的权限 rwx --0664 --rw -rw -r
#include
int close(int fd);
参:open返回值。
成功返回0
失败返回-1
ssize_t read(int fd, void *buf, size_t count);
参数:
fd : 打开的文件描述符 --- open() 返回值
buf: 存储读取的数据的 缓冲区
count: 前面缓冲区的大小 size_t无符号整数 ssize_t 有符号
返回值:
成功:没读到文件末>0否则=0
失败:error -1
#include
ssize_t write(int fd, const void *buf, size_t count);
参数:
fd : 打开的文件描述符 --- open() 返回值
buf: 存储写出的数据的 缓冲区地址
count:数据的大小
sterror函数
#include
char* sterror(int errnum);
参数:错误号 --errno 当前程序的唯一全局变量
返回值:错误号对应的错误描述
perror函数
#include
void perror(const char *s);
参数:用户自定义的错误信息:perror函数,会自动与error函数的错误描述拼接
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int n = 1;
//创建用于储存的数据缓冲区
char buf[4096];
//打开源文件
int fd1 = open(argv[1],O_RDONLY);
if(fd1 == -1)
{
perror("open src err:");
exit(1);//程序非正常结束
}
//打开目标文件
int fd2 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0644);
if(fd2 == -1)
{
perror("open dst err:");
exit(1);//程序非正常结束
}
// 、、循环从文件中读取数据,写道目标文件中
// while((n = read(fd1,buf,1024)) != 0)
while((n = read(fd1,buf,1024)))
{
if(n< 0)
{
perror("read error");
break;
}
//读取多少写多少,生成目标文件
write(fd2,buf,n);
}
//操作结束
close(fd1);
close(fd2);
return 0;
}
pcb进程控制块:
3个特殊文件
阻塞、非阻塞是设备文件、网络文件具备的属性。(不是read、write的属性)
查收阻塞的场景:
/dev/tty — 终端文件
设置/dev/tty文件为非阻塞状态 --重写打开指定O_NONBLOCK属性。
int fd = open("/dev/tty",O_RDWR|O_NONBLOCK);
#include
#include
int fcntl(int fd, int cmd, ... /* arg */ );
# 获取文件权限
int flg = fcntl(fd,F_GETFL)
#修改文件权限
flg |= O_NONBLOCK //添加非阻塞权限
fcntl(fd,F_SETFL,flg)
SYNOPSIS
#include
#include
off_t lseek(int fd, off_t offset, int whence);
fd 文件描述符
offset 偏移量
whence:起始偏移位. SEEK_SET \SEEK_CUR \SEEK_END
返回:
成功:较起始位置便宜
失败:-1
void sys_err(const char*str)
{
perror(str);
exit(1);
}
int main(int argc,char* argv[])
{
int fd = open(“lseek.txt”,O_RDWR|O_CREAT,0664);
if(fd == -1)
{
sys_err(“open err”);
}
//使用lseek拓展文件大小
int len = lseek(fd,10,SEEK_END);
printf(“len = %d\n”,len);
//必须引起IO操作,真正拓展文件
write(fd,"a",strlen("a"));
close(fd);
int ret = truncate("lseek.txt",250);
printf("ret = %d\n",ret);
return 0;
}
#include
#include
int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
#include
#include
#include
#include
#include
#include
#if 0
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 */
/* Since Linux 2.6, the kernel supports nanosecond
* precision for the following timestamp fields.
* For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last modification */
struct timespec st_ctim; /* time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
#endif
//查看文件信息命令
//deng@itcast:~/share/4th$ stat txt
//获取文件相关信息
int main(void)
{
int ret = -1;
struct stat buf;
memset(&buf, 0, sizeof(buf));
//获取文件相关信息
ret = stat("txt", &buf);
if (-1 == ret)
{
perror("stat");
return 1;
}
printf("st_dev: %lu\n", buf.st_dev);
printf("st_ino: %lu\n", buf.st_ino);
printf("st_nlink: %lu\n", buf.st_nlink);
printf("st_uid: %d\n", buf.st_uid);
printf("st_gid: %d\n", buf.st_gid);
printf("st_rdev:%lu\n", buf.st_rdev);
printf("st_size: %ld\n", buf.st_size);
printf("st_blksize: %ld\n", buf.st_blksize);
printf("st_blocks: %ld\n", buf.st_blocks);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char*str)
{
perror(str);
exit(1);
}
int main(int argc,char * argv[])
{
struct stat sbuf;
int ret = lstat(argv[1],&sbuf);
printf("file size is %ld\n",sbuf.st_size);
if(ret == -1)
{
sys_err("stat err");
}
if(S_ISREG(sbuf.st_mode)){
printf("It's a regular file");
}
else if (S_ISDIR(sbuf.st_mode))
{
printf("it's a dir\n");
}
else if( S_ISFIFO(sbuf.st_mode))
{
printf("It's is a fifo");
}
else if(S_ISLNK(sbuf.st_mode))
{
printf("It's a software link");
}
return 0;
}
如何查看软连接本身的文件内容。readlink命令或者readlink()函数
int link(const char*oldpath,const char* newpath);
int unlink(const char*pathname)
#include
#include
DIR *opendir(const char *name);
功能:打开一个目录
参数:
name:目录名
返回值:
成功:返回指向该目录结构体指针
失败:NULL
#include
#include
int closedir(DIR *dirp);
功能:关闭目录
参数:
dirp:opendir返回的指针
返回值:
成功:0
失败:-1
#include !
struct dirent *readdir(DIR *dirp);
功能:读取目录
参数:
dirp:opendir的返回值
返回值:
成功:目录结构体指针
失败:NULL
struct dirent
{
ino_t d_ino; // 此目录进入点的inode
off_t d_off; // 目录文件开头至此目录进入点的位移
signed short int d_reclen; // d_name 的长度, 不包含NULL 字符
unsigned char d_type; // d_type 所指的文件类型
char d_name[256]; // 文件名
};
d_name: 文件名。 要求长度不能超过255个有效字符。
d_type文件类型说明:
取值 | 含义 |
---|---|
DT_BLK | 块设备 |
DT_CHR | 字符设备 |
DT_DIR | 目录 |
DT_LNK | 软链接 |
DT_FIFO | 管道 |
DT_REG | 普通文件 |
DT_SOCK | 套接字 |
DT_UNKNOWN | 未知 |
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char*str)
{
perror(str);
exit(1);
}
int main(int argc,char*argv[])
{
DIR *dp;
struct dirent *sdp ;
int i = 0;
dp = opendir(argv[1]);
if(dp==NULL)
{
sys_err("opendir err");
}
while((sdp = readdir(dp))!=NULL)
{
i++;
if(i%6==0)printf("\n");
if(sdp->d_name[0]!='.')printf("%s\t",sdp->d_name);
}
printf("\n");
closedir(dp);
return 0;
}
//函数原型:
int dup(int oldfd);
参:旧文件描述符
返回值:
成功:新文件描述符
失败:-1 errno
//应用:
save_fd = dup(STDOUT_FILENO)
write(save_fd,msg,strlen(msg));//数据会被写道屏幕
#include
int dup2(int oldfd, int newfd);
功能:
通过 oldfd 复制出一个新的文件描述符 newfd,如果成功,newfd 和函数返回值是同一个返回值,最终 oldfd 和新的文件描述符 newfd 都指向同一个文件。
参数:
oldfd : 需要复制的文件描述符
newfd : 新的文件描述符,这个描述符可以人为指定一个合法数字(0 - 1023),如果指定的数字已经被占用(和某个文件有关联),此函数会自动关闭 close() 断开这个数字和某个文件的关联,再来使用这个合法数字。
返回值:
成功:返回 newfd
失败:返回 -1
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char*str)
{
perror(str);
exit(1);
}
int main(int argc,char* argv[])
{
char buf[1024];
int n;
if(argc==4)
{
if(strcmp(argv[2],">")==0)
{
int fd2 = open(argv[3],O_WRONLY|O_CREAT|O_TRUNC,0664);
if(fd2 == -1)
{
sys_err("open out err");
}
// dup2(STDERR_FILENO,fd2);
dup2(fd2,STDERR_FILENO);
}
}
int fd = open(argv[1],O_RDONLY);
if(fd == -1)
{
sys_err("open argv[1] err");
}
while(( n = read(fd,buf,sizeof(buf))))
{
write(STDOUT_FILENO,buf,n);
}
}