基本文件的输入输出
目录操作
标准I/O函数库
1. 基本文件输入输出
(1) 验证三个已打开的标准输入、标准输出和标准错误输出
// exam6-1.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFSIZ 200
int main()
{
char buf[BUFSIZ];
int n;
while((n= read(STDIN_FILENO, buf , BUFSIZ)) > 0)
write(STDOUT_FILENO, buf , n);
exit(0);
}
编译执行上述代码
$ gcc -o exam1 exam1.c //编辑并链接
# ./exam1 //执行
(2) 利用基本输入输出函数复制文件
// exam2.c
#include <stdio.h>
#include <fcntl.h>
#define PMODE 0644 // 权限的定义为 rw-r--r--
int main(int argc, char *argv[] ){
int fdin, fdout, n;
char buf[BUFSIZ];
if(argc !=3) {
fprintf(stderr, "Usage: %s filein fileout\n",argv[0]);
exit(1);
}
if((fdin = open(argv[1],O_RDONLY)) == -1) {
perror(argv[1]);
exit(2);
}
if((fdout = open(argv[2],O_WRONLY | O_CREAT |
O_TRUNC, PMODE)) == -1) {
perror(argv[2]);
exit(3);
}
while((n = read(fdin, buf, BUFSIZ)) > 0)
write(fdout,buf, n);
exit(0);
}
编译并执行上述程序
$ gcc -o exam2 exam2.c //编译并链接
$ ./exam2 exam2.c exam2.bak //备份exam2.c文件
(3) 显示文件属性信息
//exam3.c
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
//显示文件类型和文件存取权限
prntmode(struct stat *stbuf)
{
switch(stbuf->st_mode & S_IFMT) {
case S_IFDIR:
printf("directory\t");
break;
case S_IFCHR:
printf("character special file\t");
printf("special device: %d\t",stbuf->st_rdev);
break;
case S_IFBLK:
printf("block special file\t");
printf("special device: %d\t",stbuf->st_rdev);
break;
case S_IFREG:
printf("regular file\t");
break;
case S_IFIFO:
printf("named pipe\t");
break;
}
if(stbuf->st_mode & S_ISUID) printf("setuid\t");
if(stbuf->st_mode & S_ISGID) printf("setgid\t");
if(stbuf->st_mode & S_ISVTX) printf("sticky\t");
printf("permissions: %o\n",stbuf->st_mode & 0777);
}
//显示文件的属主用户和用户组
prntuser(struct stat *stbuf)
{
struct passwd *pw, *getpwuid();
struct group *grp,*getgrgid();
pw = getpwuid(stbuf->st_uid);
printf("user ID: %d name: %s\t",stbuf->st_uid,pw->pw_name);
grp = getgrgid(stbuf->st_gid);
printf("group ID: %d group: %s\n",stbuf->st_gid,grp->gr_name);
}
// 显示文件与时间相关的属性
prntimes(struct stat *stbuf)
{
char *ctime();
printf("last access: \t\t%s", ctime(&stbuf->st_atime));
printf("last modification: \t%s", ctime(&stbuf->st_mtime));
printf("last status change: \t%s", ctime(&stbuf->st_ctime));
}
main(int argc,char *argv[])
{
struct stat stbuf;
if(stat(argv[1],&stbuf) == -1) {
perror(argv[1]);
exit(1);
}
printf("file name: %s\t\t",argv[1]);
printf("device: %d\t",stbuf.st_dev);
printf("i-number: %u\n",stbuf.st_ino);
prntmode(&stbuf);
printf("links: %d\t",stbuf.st_nlink);
printf("file size: %ld\n",stbuf.st_size);
prntuser(&stbuf);
prntimes(&stbuf);
exit(0);
}
编译并运行上述代码
$ gcc -o exam3 exam3.c //编译并链接
$ ./exam3 exam2.c //显示文件exam2.c的属性
2. 目录操作
下列程序用于显示当前目录下的所有文件名
// exam4.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
int main(int argc, char *argv[])
{
DIR *dirp;
struct dirent *direntp;
if((dirp = opendir(argv[1])) == NULL) {
fprintf(stderr,"error message: %s\n",strerror(errno)); // 显示错误信息
exit(1);
}
while((direntp = readdir(dirp)) != NULL)
printf("%s\n", direntp->d_name);
closedir(dirp);
exit(0);
}
编译并执行上述代码
$ gcc -o exam4 exam4.c
$ ./exam4
3. 标准I/O函数库
(1) 验证标准I/O函数库的内部缓存机制
//exam5.c
#include <stdio.h>
main()
{
int i;
for (i=0; i<5; i++)
{
printf("i=%d ",i);
sleep(2);
}
}
编译并执行上述代码
$ gcc -o exam5 exam5.c
# ./exam5 //经过若干秒后显示运行结果
(2) 演示标准I/O函数库与毕本I/O函数间关系
// exam6.c
#include <stdio.h>
int main()
{
printf("h");
printf("e");
printf("l");
printf("l");
printf("o");
printf("\n");
fflush(stdout);
exit(0);
}
编译并执行上述代码
$ gcc -o exam6 exam6.c
$ strace exam6 //跟踪最终实现
4. 思考题
(1) 思考pwd命令的实现原理
(2) 标准I/O函数库的特点