Day26、文件操作(write)、文件的附加属性、文件重定向、mmap映射文件
来源:互联网 发布:ewb电路仿真软件 编辑:程序博客网 时间:2024/06/15 23:38
昨天作业:文件显示 Mycat函数:
1#include<stdio.h>
2#include<sys/types.h>
3#include<fcntl.h>
4#include<sys/stat.h>
5#include<unistd.h>
6int main(int argc,char *argv[]){
7 int fd,ret;
8 char buf;
9 if(argc!=2){
10 printf("usage:mycat filename\n");
11 return 2;
12 }
13 //以只读的方式打开文件
14 fd=open(argv[1],O_RDONLY);
15 if(fd= =-1){
16 perror("open");
17 return 1;
18 }
19 while((ret=read(fd,&buf,1))>0){
20 printf("%c",buf);
21 }
22 //关闭文件
23 close(fd);
24 return 0;
25 }
tarena@tarena-virtual-machine:~/day26$ gccmycat.c
tarena@tarena-virtual-machine:~/day26$./a.out
usage:mycat filename
tarena@tarena-virtual-machine:~/day26$./a.out hello.c
#include<stdio.h>
int main(){
printf("c\n");
return 0;
}
一、 文件操作的遗留部分
write (2)
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:将buf里的内容,写入到文件描述符为fd的文件里,预计写入count个字节
参数:
fd:文件描述符
buf:指定的一个地址
count:欲写入的字节数
返回值:
返回写入的字节数,如果写入失败,返回-1,且errno被设置
举例:write.c
1 #include<stdio.h>
2#include<sys/types.h>
3 #include<fcntl.h>
4 #include<sys/stat.h>
5 #include<unistd.h>
6 #include<string.h>
7 int main(int argc,char*argv[]){
8 int fd,ret;
9 char buf[12]="tang";
10 if(argc!=2){
11 printf("usage:mycatfilename\n");
12 return 2;
13 }
14 //以写的方式打开文件
15 fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0644);
16 if(-1= =fd){
17 perror("open");
18 return 1;
19 }
20 //将buf数组里的内容写入到文件里
21 write(fd,buf,strlen(buf)+1);
22 //关闭文件
23 close(fd);
24 return 0;
25 }
tarena@tarena-virtual-machine:~/day26$ ./a.out ss.txt
tarena@tarena-virtual-machine:~/day26$ cat ss.txt
tang
举例:进一步改写myacat.c
#include<stdio.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<unistd.h>
int main(int argc,char *argv[]){
int fd,ret;
char buf;
if(argc!=2){
printf("usage:mycat filename\n");
return 2;
}
//以只读的方式打开文件
fd=open(argv[1],O_RDONLY);
if(fd==-1){
perror("open");
return 1;
}
while((ret=read(fd,&buf,1))>0){
//文件描述符1代表标准输出
write(1,&buf,1); //前面的1代表标准输出(输出到屏幕,如果是fd就是输出到前面open打开的文件里)
}
//关闭文件
close(fd);
return 0;
}
tarena@tarena-virtual-machine:~/day26$./a.out myacat.c
补充:
1、 在文件操作中,尽量使用同一类的函数。
类有两种,(系统调用、库函数)
2、 文件描述符0、1、2(特殊的文件描述符)
UC:
0代表标准输入 STDIN_FILENO (scanf)
1代表标准输出 STDOUT_FILENO (printf)
2代表标准错误 STDERR_FILENO
标C:
0:stdin
1:stdout
2:stderr
3、 文件的每一行最后一个字符是\n
作业:封装一个函数,实现读取文件一行的功能
readline.c
lseek(2)
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
举例
a.txt abcdefghijkl
lseek.c
1 #include<stdio.h>
2 #include<sys/types.h>
3 #include<sys/stat.h>
4 #include<fcntl.h>
5 #include<unistd.h>
6 int main(int argc,char*argv[]){
7 int fd;
8 char buf;
9 fd=open("a.txt",O_RDONLY);
10 if(fd==-1){
11 perror("open");
12 return 0;
13 }
14 //3L 3是长整型,后面跟L是长整形,若U是无符号型
15 lseek(fd,3L,SEEK_SET);
16 read(fd,&buf,1);
17 printf("%c\n",buf); //从第三个后,第4个开始
18
19 lseek(fd,-2,SEEK_CUR);
//读完d后,位置定到d和e之间,接下来要读e,-2表示往前挪两个,到b和c之间,所以读出c
20 read(fd,&buf,1);
21 printf("%c\n",buf);
22 close(fd);
23 return 0;
24 }
tarena@tarena-virtual-machine:~/day26$ ./a.out
d
c
作业:写文件复制命令!!!!!!打包到库文件 《unix高级环境编程》>
cp 源文件 目的文件
mycp 源文件 目的文件
实现文件的复制 (认真考虑每个细节)
二、 文件的附加属性(文件的元数据)
之前操作的是文件的内容,现在操作文件的属性
-rw-rw-r-- 1tarena tarena 13 9月 1 11:04 a.txt
除了文件的名字以外,其它都是文件的属性
每个文件都有且只有一个对应的inode(图在笔记上)
如果两个文件的inode是同一个,则这两个文件是硬链接文件,1是硬链接数
(软链接是快捷方式)
tarena@tarena-virtual-machine:~/day26$ ls-l a.txt
-rw-rw-r-- 1 tarena tarena 13 9月 1 11:04 a.txt
tarena@tarena-virtual-machine:~/day26$ ln a.txt b.txt
tarena@tarena-virtual-machine:~/day26$ ls-l a.txt
-rw-rw-r-- 2 tarena tarena 13 9月 1 11:04 a.txt
查看inode的内容命令:
stat 文件名
tarena@tarena-virtual-machine:~/day26$ stata.txt
文件:"a.txt"
大小:13 块:8 IO 块:4096 普通文件
设备:801h/2049d Inode:1067314 硬链接:2
权限:(0664/-rw-rw-r--) Uid:( 1000/ tarena) Gid:( 1000/ tarena)
最近访问:2016-09-0111:14:05.027827759 +0800
最近更改:2016-09-0111:04:18.407843943 +0800
最近改动:2016-09-0111:39:22.339785767 +0800
创建时间:-
tarena@tarena-virtual-machine:~/day26$ statb.txt
文件:"b.txt"
大小:13 块:8 IO 块:4096 普通文件
设备:801h/2049d Inode:1067314 硬链接:2
权限:(0664/-rw-rw-r--) Uid:( 1000/ tarena) Gid:( 1000/ tarena)
最近访问:2016-09-0111:14:05.027827759 +0800
最近更改:2016-09-0111:04:18.407843943 +0800
最近改动:2016-09-0111:39:22.339785767 +0800
创建时间:-
tarena@tarena-virtual-machine:~/day26$
a和b对应同一个inode
文件属性在inode里,如果获得inode里的文件属性信息? fstat ( 2 )
man 2 fstat
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int fstat(int fd, struct stat *buf);
(struct stat*buf ,通过这个参数可以带回一个值(在这个函数里把数写在这个地址里),这种参数叫做“值__结果参数”)
功能:将fd指定文件的inode中文件的属性信息通过buf带回
参数:
fd:文件描述符
buf:用来带回inode中文件的属性信息
返回值:
0:成功
-1:失败,errno被设置
掌握struct stat结构体每个字段的含义
struct stat {
ino_t st_ino; /* inode number */ inode号
mode_t st_mode; /* protection */ 权限
nlink_t st_nlink; /* number of hard links */ 硬链接数
uid_t st_uid; /* user ID of owner */ 用户id
gid_t st_gid; /* group ID of owner */ 组id
off_t st_size; /* total size, in bytes */ 文件的字节数
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 */ 最后更新时间
};
举例练习:
tarena@tarena-virtual-machine:~/day26$ ls-l a.txt
-rw-rw-r-- 2 tarena tarena 13 9月 1 11:04 a.txt
vi fstat.c
1#include<stdio.h>
2#include<time.h>
3#include<sys/types.h>
4#include<sys/stat.h>
5#include<unistd.h>
6int main(int argc,char *argv[]){
7 struct stat sb;
8 int ret;
9 //获取inode中的文件属性信息
10 ret=stat(argv[1],&sb);
11 if(ret==-1){//失败
12 perror("stat");
13 return 1;
14 }
15 printf("stat successful.....\n");
16 //输出文件的inode号
17 printf("inode number....%ld\n",(long)sb.st_ino);
18 //输出文件的权限
19 printf("mode:%lo\n",(unsigned long)sb.st_mode);
20 //输出文件的大小
21 printf("size:%lld\n",(longlong)sb.st_size);
22 //输出文件的uid和gid
23 printf("uid:%ld\tgid:%ld\n",(long)sb.st_uid,(long)sb.st_gid);
24 //输出文件时间
25 printf("Last status change: %s\n",ctime(&sb.st_ctime));
26 return 0;
27 }
tarena@tarena-virtual-machine:~/day26$ gccfstat.c
tarena@tarena-virtual-machine:~/day26$./a.out a.txt
stat successful.....
inode number....1067314
mode:100664
size:13
uid:1000 gid:1000
Last status change: Thu Sep 1 11:39:22 2016
tarena@tarena-virtual-machine:~/day26$ stata.txt
文件:"a.txt"
大小:13 块:8 IO 块:4096 普通文件
设备:801h/2049d Inode:1067314 硬链接:2
权限:(0664/-rw-rw-r--) Uid:( 1000/ tarena) Gid:( 1000/ tarena)
最近访问:2016-09-0111:14:05.027827759 +0800
最近更改:2016-09-0111:04:18.407843943 +0800
最近改动:2016-09-0111:39:22.339785767 +0800
创建时间:-
tarena@tarena-virtual-machine:~/day26$
(vi stat.c +23 直接到23行)
getpwuid (3) man getpwuid
getpwnam 得到文件名的函数 显示a.txt
getgrgid (3)
ctime(3)
作业:myls的实现!! (注意将一些功能封装成函数)
三、文件描述符的复制
dup (2)
#include <unistd.h>
int dup(intoldfd);
功能:复制oldfd文件描述符到新的文件文件描述符中
参数: oldfd 旧的fd
返回值:
-1:失败 errno被设置
成功返回新的描述符,这个描述符是最小的没有被使用的文件描述符
dup2
int dup2(intoldfd, int newfd);
功能:将旧的文件描述符复制给新的文件描述符
参数:
Oldfd:旧文件描述符
Newfd新文件描述符
返回值
-1:失败 errno被设置
成功返回新的描述符,这个描述符是最小的没有被使用的文件描述符
举例:dup.c 重要
1 #include<stdio.h>
2 #include<sys/stat.h>
3 #include<sys/types.h>
4 #include<fcntl.h>
5 #include<unistd.h>
6 #include<string.h>
7 int main(){
8 int fd,s_fd;
9 char *msg="this is a test\n";
10 //fd=3,3指向文件
11 fd=open("somefile",O_RDWR|O_CREAT,0644);
12 if(fd==-1){
13 perror("open");
14 return 1;
15 }
16 //s_fd=4
17 s_fd=dup(STDOUT_FILENO);
18 dup2(fd,STDOUT_FILENO);//1、3、4都指向文件somefile
19 close(fd);//文件描述符3给关掉
20 write(STDOUT_FILENO,msg,strlen(msg));
21 //改变了标准输出文件描述符的方向
22 dup2(s_fd,1);//将s_fd复制给1
23 //本来输入到屏幕上,现在输出到文件somefile里
24 //重定向
25 write(STDOUT_FILENO,msg,strlen(msg));
26 close(fd);//文件描述符3给关掉
27 return 0;
28 }
tarena@tarena-virtual-machine:~/day26$./a.out
this is a test
文件重定向的原理:dup.c
四、 mmap映射文件
使用read/write读写文件,效率比较低
为了提高效率,使用mmap将文件直接映射到虚拟地址空间里。对这块内存空间的操作,直接反映到文件里。
举例:
首先写个文件:
tarena@tarena-virtual-machine:~/day26$vi hello
tarena@tarena-virtual-machine:~/day26$od -tx1 -tchello 命令
0000000 68 65 6c 6c 6f 0a
h e l l o \n
0000006
vi mmap.c
1 #include<sys/mman.h>
2 #include<stdio.h>
3 #include<sys/types.h>
4 #include<sys/stat.h>
5 #include<fcntl.h>
6 #include<unistd.h>
7 int main(){
8 int fd;
9 fd=open("hello",O_RDWR);
10 if(fd==-1){
11 perror("open");
12 return 1;
13 }
14 void *handle=mmap(NULL,6,PROT_WRITE,MAP_SHARED,fd,0);
15 if(handle= =MAP_FAILED){
16 perror("mmap");
17 return 2;
18 }
19 int *p=(int *)handle;
20 p[0]=0x30313233;
21 close(fd);
22 munmap(handle,6);
23 return 0;
24 }
tarena@tarena-virtual-machine:~/day26$gcc mmap.c
tarena@tarena-virtual-machine:~/day26$./a.out
tarena@tarena-virtual-machine:~/day26$od -tx1 -tc hello
0000000 33 32 31 30 6f 0a
3 2 1 0 o \n
0000006
前4个字节变了,因为程序中int*p=(int *)handle;,只改了int 型个字节,int是4个字节
- Day26、文件操作(write)、文件的附加属性、文件重定向、mmap映射文件
- mmap()映射硬盘的文件
- 文件内存映射(mmap)
- 内存映射文件(MMAP)
- 文件映射mmap
- linux mmap 映射文件
- linux中使用内存映射(mmap)操作文件的方法
- mmap之内存映射文件与常规文件操作比较
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Linux的mmap文件内存映射机制
- Day25、malloc 内存分配、mmap内存映射、文件的操作(文件描述符、open\close\read)
- Codeforces Round #343 (Div. 2) E. Famil Door and Roads (树形dp,lca)★ ★ ★
- banner字体
- UVA-10780-Again Prime? No Time(素数分解)
- 164. Maximum Gap
- Day26、文件操作(write)、文件的附加属性、文件重定向、mmap映射文件
- 中国的程序员与日本程序员
- 开博客的目的
- POJ 1226
- CS231n课程:反向传播学习记录
- Codeforces702F. T-Shirts
- servlet——filter(过滤器)学习
- Java_线程—经典的例子:生产者和消费者
- android Gson解析 (同json解析方式)