linux的文件操作是用标识符来代替文件指针
int fd; 与 FILE* fp;
1)man 2 open 就可以看到read的相关用法
int open (const char *pathname,int flags);
int open(const char *pathnameint flags,mode_t mode);
例子1:
int fp;
fp=open(argv[1],O_RDONLY);
其中的flags为读取类型,系统已经宏定义好了fp为描述赋,scanf 是从描述符为0的文件进行读,printf对描述赋为1的文件进行输出(屏幕),2的时候是报错
例子2:
int fp;
fp=open(argv[1],WRONLY|O_CREAT,0666);
WRONLY|O_CREAT的意思是如果没有就创建该文件,前面的0表示8进制,普通用户掩码umask为002,所以实际权限为(mode&(~umask)) ,(666&(~002))=666-002=664 .
O_CREAT的位置也可以时O_TRUNC将文件清空后在写,O_APPEND在文件后面追加
2)man 2 read
例子1
这个相当于拷贝的功能 ./my_copy ./1.cpp ./2.cpp 把1拷贝到2
diff 1.cpp 2.cpp
比较1与2的不同
#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<memory.h>
using namespace std;
int main(int argc ,char *argv[]){
int fp_in,fp_out;
fp_in=open(argv[1],O_RDONLY);
fp_out=open(argv[2],O_WRONLY|O_CREAT,0666);
char buf[128];
while(memset(buf,0,127)){
int nread=read(fp_in,buf,128);//返回值是成功读的字节数,失败的时候返回-1
write(fp_out,buf,nread);//nread是指定输入长度
}
}
例子2:
说明read是以一块一块读的,自己定义的127
int main(int argc,char *argv[]){
int fd;
fd=open(argv[1],O_RDONLY);
if(fd==-1){
perror("open failed");
}
char buf[128];
int readn;
while(memset(buf,0,128)){
readn=read(fd,buf,127);//从
printf("readn=%d,%s",readn,buf);
if(readn==0){
printf("read finishen\n");
break;
}
}
}
例子3
从键盘读入后readn的位置没有0;需手动加入
int readn=read(0,buf,128);
buf[readn]='\0';
输出到屏幕,标识符为1,buf为一个数组,nread为长度
write(1,buf,nread);
3)
printf("hello");
while(1){}
在linux系统下没有输出,因为刷新缓冲区有三种情况
1,/n 2,缓冲区满 3.程序结束
可以理解刷新就是输出,以上代码因为没有/n,缓冲区也没满,所以没输出
4)
ls -ali 显示所有a(阿)节点
ln -s main main.exe 给main建立了一个快捷方式main.exe所以main 和main.exe阿节点相同
5)
open 2 stat
获取文件信息的结构体
其中用到ctime得到标准时间格式,getpwuid得到用户名的结构体,getgrgid得到组名的结构体,均可用man得到相应的用法
该程序主要是模仿ls -l的功能
#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<memory.h>
#include<stdio.h>
#include<pwd.h>
#include<grp.h>
using namespace std;
char *time_format(char *src){
int len=strlen(src);
for(int i=len-1;i>=0;i--){
if(src[i]==':'){
src[i]='\0';
break;
}
}
return src+4;
}
void mode_to_string(mode_t mode,char *dest){
// putchar(1);
memset(dest,'_',15);
// for(int i=0;i<15;i++)
// dest[i]='_';
if(S_ISDIR(mode))//判断是不是文件
dest[0]='d';
if(S_ISREG(mode))
dest[0]='_';
if(mode & S_IRUSR)
dest[1]='r';
if(mode & S_IWUSR)
dest[2]='w';
if(mode & S_IXUSR)
dest[3]='x';
if(mode & S_IRGRP)
dest[4]='r';
if(mode & S_IWGRP)
dest[5]='w';
if(mode & S_IXGRP)
dest[6]='x';
if(mode & S_IROTH)
dest[7]='r';
if(mode & S_IWOTH)
dest[8]='w';
if(mode & S_IXOTH)
dest[9]='x';
dest[10]='\0';
// printf("Mode:%s\n",dest);
}
int main(int argc,char *argv[]){
struct stat my_stat;
memset(&my_stat,0,sizeof(my_stat));
stat(argv[1],&my_stat);
printf("Ino:%u\n",(unsigned)my_stat.st_ino);
printf("Mode:%x\n",my_stat.st_mode);
printf("nlike:%u\n",my_stat.st_nlink);
printf("uid:%u\n",my_stat.st_uid);
printf("gid:%u\n",my_stat.st_gid);
printf("size:%u\n",(unsigned)my_stat.st_size);
printf("atime:%s\n",time_format(ctime(&my_stat.st_atime)));
char dest[15];
mode_to_string(my_stat.st_mode,dest);
printf("Mode:%s\n",dest);
printf("userid:%s groupId:%s\n",getpwuid(my_stat.st_uid)->pw_name,getgrgid(my_stat.st_gid)->gr_name);
printf("---------------------------------------------------\n");//一下是模仿ls -l的功能
printf("%11s%2u%5s%5s%5u%15s%s\n",dest,my_stat.st_nlink,getpwuid(my_stat.st_uid)->pw_name,getgrgid(my_stat.st_gid)->gr_name,(unsigned)my_stat.st_size,time_format(ctime(&my_stat.st_atime)),argv[1]);
}
6)重定向
dup2(fp,0) 将标识符fp改成0,scanf读入的时候就从argv[1]中读
#include<iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include<stdio.h>
#include<unistd.h>
#include <fcntl.h>
using namespace std;
int main(int argc,char *argv[]){
int fp_in;
fp_in=open(argv[1],O_RDONLY);
if(fp_in==-1){
printf("failed\n");
return 0;
}
dup2(fp_in,0);
char buf[100];
scanf("%s",buf);
printf("%s\n",buf);
}
如果改成fp=open(argv[1],O_WRONLY|O_CREAT,0666);
dup2(fp,1);
printf 就是输出到指定的文件中