概述
I/0:
std(标准): 键盘 屏幕
非标准: 打印机...
Linux系统的文件操作:
特点:不带缓冲
API:
打开文件:
int open(const char* PATH,int flag,int mode);
注:返回的是文件的描述符(下标>=0) 失败:返回-1
最小空元素文件描述符的下标()
操作:
读: long read(int,void*,size_t)
写: long write(int,void*,size_t)
返回值:实际读/写的字节数
关闭:close(int fd)
fd:文件的描述符(下标),
关闭文件描述符(系统来清空)
文件的位置:
lseek(fd,offset,whence);
注:每次打开的文件返回>2
因为标准I/O使用较频繁,从init把标准设备打开。之后运行每一个进程都会拷贝父进程。
fd 0 键盘
fd 1 屏幕
fd 2 标准错误输出
文件流的重定向:
Shell: > 重定向
>> 追加向
< <<
API: int dup(oldfd) //复制出oldfd,返回新的描述符
dup2(oldfd,newfd)//复制oldfd 返回新的
1、如果oldfd不为有效fd,都会失败
2、newfd与oldfd相同的描述符,则不做任何事情。
#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
using namespace std;
int main()
{
//1打开文件:
//int fd=open("data",O_CREAT|O_WRONLY|O_TRUNC,0644);//不存在,则创建。存在截断
int fd =open("data",O_WRONLY);//
if(fd<0)
{
perror("data failn");
}
//位移:
lseek(fd,0,SEEK_END);
//2操作
//写入
cout<<"写入的长度"<< write(fd,"123456",6)<<endl;
//3关闭
close(fd);
return 0;
/*
//1打开
int fd=open("data",O_RDONLY);
cout<<fd<<endl;
char ch;
read(fd,&ch,1);//fd==3
cout<<ch<<endl;
//3关闭
close(fd);
*/
//从键盘读取
/*
char ch;
read(0,&ch,1);
cout<<ch<<endl;
*/
write(1,"abcdefn",7);
}
dup() 的功能实现 .
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
using namespace std;
int main()
{
//1打开文件
int fd=open("data1",O_CREAT|O_TRUNC|O_WRONLY,0644);
//2dup
int fd2=dup(1);//1屏幕
cout<<fd<<" "<<fd2<<endl;
//写入:
write(fd,"abc",3);//fd为data1
write(fd2,"abc",3);
write(1,"efg",3);
//3关闭
close(fd);
}
dup2的实现 , dup2(old,new)复制old复制给new,(new关闭).
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
using namespace std;
int main()
{
//1打开文件
int fd=open("data4",O_CREAT|O_WRONLY|O_TRUNC,0644);
cout<<fd<<endl;
//写入到data4
write(fd,"abcdef",6);
//dup2(old,new)复制old复制给new,(new关闭)
cout<<dup2(1,fd)<<endl;//先关闭fd,再将1复制给fd
write(fd,"134434",6);
//3关闭
close(fd);
}
将数据重定向到文件中 , 然后再重定向到屏幕上 , 文件描述符 , dup(1)的 1 是屏幕 , int Scree=dup(1); 这是将屏幕的文件描述符复制到 Scree中 , 用于储存 .
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
using namespace std;
//完成打印1-100,打印到data2中
int main()
{
//将屏幕的文件描述符复制 screen==3
int Scree=dup(1); //scree==3;
//关闭屏幕
close(1);
//打开文件:返回文件的描述符(下标)
int fd=open("data4",O_CREAT|O_WRONLY|O_TRUNC,0644);
cout<<fd<<endl; //fd==3
int i=0;
while(i++<=100)
cout<<i<<endl;
//再显示到屏幕
int data2=dup(1); //复制1(data2),返回值为4
close(1); //关闭data2
dup(3);
i=0;
while(i++<=100)
cout<<i<<endl;
close(fd);
}
1、Linux一切设备皆文件
1、普通文件:文本文件(ASCII),二进制文件(纯二进制文件)
2、目录文件(director):存放文件的
3、字符特殊文件(character)
4、块特殊文件(block)
5、FIFO(符号p):有名管道文件,用于进程间通信,是一种纯软机制。
6、套接口(socket:符号s):用于实现跨机进程间的网络通信,当然也可用于实现本地(本机)
7、符号连接(symbolic)
2、普通文件:
1打开 返回的文件的描述 int open(...)
2操作
读 read()
写 write()
位移:lseek()
3、关闭 close
3、文件的属性:
shell: ls -l /ll
1、获取文件的属性API:
int stat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
path:路径
fd:文件的描述符
struct stat 文件的描述符的属性
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 file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
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 */
};
其他API:
将时间戳转换为时间字符串: ctime(time_t*);
2.1、普通文件(regular file:符号-),其又分为如下两种
a)、文本文件(ascci二进制文件)
b)、二进制文件(纯二进制文件)
对linux内核而言,这两种文件并无区别,具体如何解释均有应用程序说了算。
2.2、目录文件(director file:符号d):一种特殊的文件,用以包含其它文件的文件名字和指向这些
文件对应i节点的节点编号,目录允许读,那么用户就可以读目录文件,但是只有内核可以写目录 文件。
2.3、字符特殊文件(character special file:符号c):对应字符设备。
2.4、块特殊文件(block special file:符号b):对应块设备(如磁盘等)。
2.5、FIFO(符号p):有名管道文件,用于进程间通信,是一种纯软机制。
2.6、套接口(socket:符号s):用于实现跨机进程间的网络通信,当然也可用于实现本地(本机)
进程间的通信。
2.7、符号连接(symbolic link:符号l):用以指向另外一个文件,类似于windos界面下的快捷图标。
所有的这些文件中,普通文件数量最多,最常见,其次是目录文件。
文件的属性 .
#include<iostream>
#include<time.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
using namespace std;
//#define S_ISREG(x) 表达式1?表达式2:表达式3
int main()
{
//获取某文件的属性:
struct stat st;
if(0==stat("./msg",&st))
{
//节点号
cout<<st.st_ino<<endl;
//大小
cout<<st.st_size<<endl;
//权限(8进制) ------
//cout<<oct<<st.st_mode<<endl;
if(S_ISREG(st.st_mode))//0100664//是否是普通文件
{
cout<<"-";
}
else if(S_ISDIR(st.st_mode))//是否是文件夹
{
cout<<"d";
}
cout<<endl;
//时间
cout<<ctime(&st.st_ctime)<<endl;
}
return 0;
}
文件的属性的判断 .
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
using namespace std;
int main()
{
char title[]="[****CHH@CHH ~]";
char cmd[255]="";
int pid;
char* matter[100]={NULL}; //100个地址
int i=0;
//父进程
while(1)
{
cout<<title; //输出标题
gets(cmd); //输入
pid=fork();
int flag=0;
if(pid>0)
{
wait(NULL);
}
else if(0==pid)
{
//解析字符串
matter[i]=strtok(cmd," ");
while((matter[++i]=strtok(NULL," "))!=NULL)
{
//替换子进程信息
if(strcmp(">",matter[i])==0)
{
int Scree=dup(1);
close(1);
int fd=open("data8",O_CREAT|O_TRUNC|O_WRONLY,0644);
matter[i]={NULL};
execvp(matter[0],matter);
close(1);
dup(Scree);
}
else if(strcmp(">>",matter[i])==0)
{
int Scree=dup(1);
close(1);
int fd=open("data8",O_CREAT|O_WRONLY|O_APPEND,0644);
matter[i]={NULL};
execvp(matter[0],matter);
close(1);
dup(Scree);
}
execvp(matter[0],matter);
}
}
}
return 0;
}
最后
以上就是风趣曲奇为你收集整理的Linux 文件&file描述符,文件属性 ls -l , stat的全部内容,希望文章能够帮你解决Linux 文件&file描述符,文件属性 ls -l , stat所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复