0是标准输入STDIN_FILENO,1是标准输出STDOUT_FILENO,2是标准错误输出STDERR_FILENO
例1:向标准输出文件输出,写文件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //unistd.h 是 C 和 C++ 程序设计语言中提供对 POSIX 操作系统 API 的访问功能的头文件的名称
#include<string.h>
void printArr(char* str);
int main(void)
{
char buf[100]={0};
strcpy(buf,"abcsdfggh\n");
//printf std for standard output,
//STDOUT_FILENO is a standard output file
//write(STDOUT_FILENO,buf,strlen(buf));
printArr(buf);
return 0;
}
void printArr(char* str)
{
if(str==NULL)
{
return;
}
write(STDOUT_FILENO,str,strlen(str));
}
例2:读文件
int main(void)
{
char buf[100]={0};
read(STDIN_FILENO,buf,sizeof(buf));
//可以处理空格与越界(限制sizeof(buf),越界自动截取)
printf("%s\n",buf);
return 0;
}
打开文件描述符
需要包含以下三个头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
//mode = mode&~umask,即新的权限是所写的权限与掩码取反相与,是逻辑减法
655
022
655
如果mode为655 它里面并没有022元素,故仍然为655 (关于mode取它的补数)
int creat(const char *pathname, mode_t mode);
例:
int main(void)
{
umask(0);//重新指定掩码值,使其不再从shell继承0022
int fd = open("opentest3.txt",O_WRONLY|O_CREAT,0777);
if(fd == -1)
{
ERR_EXIT("open error");
}
printf("open success\n");
return 0;
}
flags指的是打开该文件的方式:
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:读写
O_CREAT:如果不存在就创建一个
O_APPEND:追加
O_EXCL:如果文件存在,强制open失败,与O_CREAT配合使用
O_TRUNC:在open时,将文件内容清空
O_SYNC:在write时,自动同步磁盘
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
//将数据写入到内核缓冲区但还未同步到磁盘上,可以调用fsync函数进行同步,也可以在open时指定同步选项O_SYNC
int fsync(int fd);
int fdatasync(int fd);// 它只保证开打文件的数据全部被写到物理设备上,但是一些元数据并不是一定的,这也是它与fsync的区别。
ssize_t read(int fd, void *buf, size_t count);
open成功后会返回一个文件描述符,失败会返回-1,
并设置errno变量(需要添加errno.h头文件)
read()会把参数fd所指的文件传送nbyte个字节到buf指针所指的内存中。若参数nbyte为0,则read()不会有作用并返回0。返回值为实际读取到的字节数,如果返回0,表示已到达文件尾或无可读取的数据。错误返回-1,并将根据不同的错误原因适当的设置错误码。
write()会把指针buf所指的内存写入count个字节到参数fd所指的文件内。当然,文件读写位置也会随之移动。
如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入errno中。
errno是一个数,它的不同值代表不同错误,可以使用strerror(errno)来读取
例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include<string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<errno.h>
int main(void)
{
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
/*将这三个关掉后打开的文件描述符从0开始不再是3
* 预先默认值是0 1 2 如果只将STDOUT_NO关掉
* 则1是空的那么新打开的会占用1描述符
* 可以ps -u 进程名 获取进程ID
* 进入proc查看ID,进入ID
* 进入fd查看
*/
int i = open("hell.c",O_RDONLY);
if(i==-1)
{
printf("%s\n",strerror(errno));
}
else
{
printf("%d\n",i);
close(i);
}
return 0;
}
tty:终端命令
例:通过打开另一终端,将数据输入到另一终端
int main(void)
{
close(STDOUT_FILENO);
int j = open("/dev/pts/0",O_WRONLY);//1
int i = open("hell.c", O_RDONLY);//3
if (i == -1)
{
printf("%s\n", strerror(errno));
} else
{
while(1)
{
printf("j==%d,i==%d\n",j,i);
sleep(1);//linux下sleep是以秒计时的,usleep(1000000)是以微秒计时的
}
close(i);
}
return 0;
}
//打开不定大小文件,并输出到终端
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include <fcntl.h>
int main(int arg,char *args[])
{
if(arg<2)
return -1;
int fd = open(args[1],O_RDONLY);
if(fd==-1)
{
printf("error occur %s\n",strerror(errno));
}
else
{
printf("the fd = %d\n",fd);
char buf[100]={0};
while(read(fd,buf,sizeof(buf)-1) > 0)
//从fd读,读sizeof(buf)-1,防止将\0冲掉
{
printf("%s",buf);
memset(buf,0,sizeof(buf));
}
close(fd);
}
return 0;
}
//往文件写
int main(int arg,char *args[])
{
if(arg<2)
{
printf("open file error");
return -1;
}
int fd = open(args[1],O_RDWR|O_APPEND);
if(fd==-1)
{
printf("error occur %s\n",strerror(errno));
}
else
{
printf("the fd = %d\n",fd);
char buf[100]={0};
strcpy(buf,"what a hell!,the world is hell\n");
int nbyte = write(fd,buf,strlen(buf));
if(nbyte<=0)
{
printf("end of file or error");
}
close(fd);
}
return 0;
}