#include <stdio.h>
#include <unistd.h> //write()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PER_IO_BYTES 4096
int myOpen(const char *pathname,mode_t mode)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, mode | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\n", strerror(errno));
}
}
return fd;
}
int main(int argc,char *argv[])
{
int fdForRead=-1;
fdForRead=myOpen(argv[1],O_RDONLY);
if(-1==fdForRead)
{
return -1;
}
int fdForWrite=-1;
fdForWrite=myOpen(argv[2],O_WRONLY);
if(-1==fdForWrite)
{
close(fdForRead);
return -1;
}
unsigned char caBuf[PER_IO_BYTES]={'\0'};
int ret=0;
while(1)
{
memset(caBuf,'\0',PER_IO_BYTES);
ret =read(fdForRead,caBuf,PER_IO_BYTES);
if(-1==ret)
{
printf("read error:%s\n",strerror(errno));
return -1;
}
else if(0==ret)
{
printf("copy file success\n");
break;
}
else
{
printf("read %d bytes from %s\n",ret,argv[1]);
ret=write(fdForWrite,caBuf,ret);
if(-1==ret)
{
printf("write error:%s\n",strerror(errno));
return -1;
}
printf("write %d bytes from %s\n",ret,argv[2]);
}
}
return 0;
}
#include <stdio.h>
#include <errno.h> //errno
#include <string.h> //strerror()
#include <unistd.h> //read() write()
/*open*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if 0
//头文件: /usr/include/unistd.h
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
#endif
//默认打开的三个文件:
//标准输入, 标准输出,标准错误输出
//标准输入:0 -- STDIN_FILENO
//标准输出:1 -- STDOUT_FILENO
//标准错误输出:2 -- STDERR_FILENO
int main(int argc, char *argv[])
{
char caBuf[32] = {'\0'};
//read:默认阻塞读终端,
// 即若标准输入没有数据可读,则阻塞直到有数据到来
// 阻塞即为等待数据的输入
// 可以结合scanf()函数来理解
int ret = read(STDIN_FILENO, caBuf, sizeof(caBuf));
if (-1 == ret)
{
printf("read error:%s\n", strerror(errno));
}
else
{
if (caBuf[31] != '\0')
{
caBuf[31] = '\0';
}
printf("%s\n", caBuf);
}
return 0;
}
#include <stdio.h>
#include <errno.h> //errno
#include <string.h> //strerror()
#include <unistd.h> //read() write()
/*open*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//头文件:/usr/include/unistd.h
//默认打开的三个文件:
//标准输入,标准输出,标准错误输入
//标准输入:0---STDIN_FILENO
//标准输出:1---STDOUT_FILENO
//标准错误输入:2---STDERR_FILENO
int main(int argc, char *argv[])
{
int fd=-1;
fd=open("/dev/tty",O_RDWR | O_NONBLOCK);
printf("fd=%d\n",fd);
char caBuf[32]={'\0'};
int ret=-1;
//read:默认阻塞读终端
//即若标准输入没有数据刻度,则阻塞直到有数据到来
//阻塞即为等待数据的输入
//可以结合scanf函数来理解
while(1)
{
memset(caBuf,'\0',sizeof(caBuf));
ret=read(fd,caBuf,sizeof(caBuf));
if(-1==ret)
{
//EAGAIN:当设置非阻塞时,若没有数据可读,则出错
//设置errno值为EAGAIN
if(EAGAIN!=errno)
{
// printf("errno=%d,%d\n",errno,EAGAIN);
printf("read error:%s\n",strerror(errno));
break;
}
printf("no data for reading\n");
sleep(1);
continue;
}
else
{
if(caBuf[31]!='\0')
{
caBuf[31]='\0';
}
printf("%s\n",caBuf);
}
}
return 0;
}
eintr
#include <stdio.h>
#include <unistd.h> //write() read() sleep()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_RDONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\n", strerror(errno));
}
}
return fd;
}
int myRead(int fd, char *pData, int iTotalSize)
{
//对形参的值进行有效性检查
if (-1 != fd && NULL != pData && iTotalSize > 0)
{
int iLeft = iTotalSize;
int iReaded = 0;
int ret = -1;
while (ret=read(fd,pData+iReaded,iLeft) && iLeft)
{
if (-1==ret)
{
//EINTR:当将要进行io操作时,被信号打断
//则io操作失败,则将errno值设置为EINTR
//这种情况下可以重新进行io操作
if(EINTR==errno||EAGAIN ==errno)
{
continue;
}
printf("read errno:%s\n",strerror(errno));
break;
}
iLeft -= ret;
iReaded += ret;
}
}
}
int main(void)
{
int fd = -1;
fd = myOpen("test.data");
if (-1 != fd)
{
char caBuf[1000100] = {'\0'};
myRead(fd, caBuf, sizeof(caBuf));
close(fd);
}
return 0;
}
- 学生结构体,写入6个学生信息,打印1,3,6位同学
- write.c
#include <stdio.h>
#include <unistd.h> //write()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define NAME_LEN 32
typedef struct Student
{
int iId;
char caName[NAME_LEN];
char cSex;
float fScore;
}Student;
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\n", strerror(errno));
}
}
return fd;
}
int main(void)
{
int fd = -1;
fd = myOpen("stu.info");
if (-1 != fd)
{
Student stu[6] = {
{1001, "zhangsan", 'f', 99},
{1002, "lisi", 'm', 79},
{1003, "wangwu", 'f', 89},
{1004,"damazi",'f',69},
{1005,"xiaofang",'m',98},
{1006,"xiaoming",'f',88}
};
int ret = -1;
int i = 0;
for (; i < 6; i++)
{
ret = write(fd, stu+i, sizeof(Student));
if (-1 == ret)
{
printf("write error: %s\n", strerror(errno));
}
else
{
printf("write %d bytes to file\n", ret);
}
}
}
return 0;
}
#include <stdio.h>
#include <unistd.h> //write() read()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define NAME_LEN 32
typedef struct Student
{
int iId;
char caName[NAME_LEN];
char cSex;
float fScore;
}Student;
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_RDONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\n", strerror(errno));
}
}
return fd;
}
int main(void)
{
int fd = -1;
fd = myOpen("stu.info");
if (-1 != fd)
{
int ret = -1;
int i=0;
Student stu;
//将Student对象的空间都设置为'\0'
memset(&stu, '\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if(-1!=ret)
{
printf("id:%d, name:%s, sex:%c, score:%.1f\n"
, stu.iId, stu.caName
, stu.cSex, stu.fScore);
}
off_t offset=lseek(fd,2*sizeof(Student),SEEK_SET);
if (-1!=offset)
{
memset(&stu, '\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if(-1!=ret)
{
printf("id:%d, name:%s, sex:%c, score:%.1f\n"
, stu.iId, stu.caName
, stu.cSex, stu.fScore);
}
}
offset=lseek(fd,5*sizeof(Student),SEEK_SET);
if (-1!=offset)
{
memset(&stu, '\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if(-1!=ret)
{
printf("id:%d, name:%s, sex:%c, score:%.1f\n"
, stu.iId, stu.caName
, stu.cSex, stu.fScore);
}
}
close(fd);
}
return 0;
}
#include <stdio.h>
#include <unistd.h> //write() read()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define NAME_LEN 32
typedef struct Student
{
int iId;
char caName[NAME_LEN];
char cSex;
float fScore;
}Student;
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_RDONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\n", strerror(errno));
}
}
return fd;
}
int main(void)
{
int fd = -1;
fd = myOpen("stu.info");
if (-1 != fd)
{
int ret = -1;
int i=0;
Student stu;
while(1)
{
//将Student对象的空间都设置为'\0'
memset(&stu, '\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if(-1!=ret)
{
printf("id:%d, name:%s, sex:%c, score:%.1f\n"
, stu.iId, stu.caName
, stu.cSex, stu.fScore);
}
off_t offset=lseek(fd,sizeof(stu),SEEK_CUR);
if (-1!=offset)
{
memset(&stu, '\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if(-1!=ret)
{
printf("id:%d, name:%s, sex:%c, score:%.1f\n"
, stu.iId, stu.caName
, stu.cSex, stu.fScore);
}
}
offset=lseek(fd,2*sizeof(stu),SEEK_CUR);
if (-1!=offset)
{
memset(&stu, '\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if(-1!=ret)
{
printf("id:%d, name:%s, sex:%c, score:%.1f\n"
, stu.iId, stu.caName
, stu.cSex, stu.fScore);
}
}
break;
}
close(fd);
}
return 0;
}
#include <stdio.h>
#include <unistd.h> //write() read() sleep()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
int fd=-1;
fd=open(argv[1],O_RDWR | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP);
if(-1 == fd)
{
printf("open error:%s\n",strerror(errno));
return -1;
}
//偏移参照位置
//文件首部,当前位置,文件尾
//返回值为距离文件首的偏移量
//第一个参数:文件描述符
//第二个参数:相对参照位置的偏移量
// 当偏移为正数时,往参照位置后偏移
// 当偏移为负数时,往参照位置前偏移
//第三个参数:参照位置SEEK_SET
//第三个参数:参照位置
off_t offset = lseek(fd,0,SEEK_END);//返回值为距离文件头的偏移量
if(-1==offset)
{
printf("lseek error:%s\n",strerror(errno));
}
else
{
printf("file size:%ld\n",offset);
}
return 0;
}
//./a.out test.data
//1234567890abcdefghijklmn
//file size=25
-
#include <stdio.h>
#include <unistd.h> //write() read() sleep()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
int fd=-1;
//当打开一个文件时,读写位置默认在文件首部
fd=open(argv[1],O_RDWR | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP);
if(-1 == fd)
{
printf("open error:%s\n",strerror(errno));
return -1;
}
//偏移参照位置
//文件首部,当前位置,文件尾
//返回值为距离文件首的偏移量
//第一个参数:文件描述符
//第二个参数:相对参照位置的偏移量
// 当偏移为正数时,往参照位置后偏移
// 当偏移为负数时,往参照位置前偏移
//第三个参数:参照位置SEEK_SET
//第三个参数:参照位置
off_t offset = lseek(fd,0,SEEK_END);//返回值为距离文件头的偏移量
if(-1==offset)
{
printf("lseek error:%s\n",strerror(errno));
}
else
{
printf("file size:%ld\n",offset);
}
//将读写位置偏移到
offset=lseek(fd,10,SEEK_SET);
printf("offset=%ld\n",offset);
char *iData="888";
write(fd,iData,strlen(iData));
close(fd);
return 0;
}
//./a.out test.data
//原来的为:1234567890abcdefghijklmn
//1234567890888defghijklmn
-
#include <stdio.h>
#include <unistd.h> //write() read() sleep()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
int fd=-1;
//当打开一个文件时,读写位置默认在文件首部
fd=open(argv[1],O_RDWR | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP);
if(-1 == fd)
{
printf("open error:%s\n",strerror(errno));
return -1;
}
//偏移参照位置
//文件首部,当前位置,文件尾
//返回值为距离文件首的偏移量
//第一个参数:文件描述符
//第二个参数:相对参照位置的偏移量
// 当偏移为正数时,往参照位置后偏移
// 当偏移为负数时,往参照位置前偏移
//第三个参数:参照位置SEEK_SET
//第三个参数:参照位置
off_t offset = lseek(fd,0,SEEK_END);//返回值为距离文件头的偏移量
if(-1==offset)
{
printf("lseek error:%s\n",strerror(errno));
}
else
{
printf("file size:%ld\n",offset);
}
//将读写位置偏移到第10位,输入888,将abc替换成了888
offset=lseek(fd,10,SEEK_SET);
printf("offset=%ld\n",offset);
char *iData="888";
write(fd,iData,strlen(iData));
//往后5个位置插入666,将678替换为666
lseek(fd,5,SEEK_SET);
write(fd,"666",3);
close(fd);
return 0;
}
// ./a.out test.data
//原来的为:1234567890abcdefghijklmn
//1234566690888defghijklmn
#include <stdio.h>
#include <unistd.h> //write() read() sleep()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PER_IO_BYTES 4096
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_WRONLY | O_CREAT | O_APPEND
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\n", strerror(errno));
}
}
return fd;
}
int main(void)
{
int fd=-1;
fd=myOpen("test.data");
char caBuf[10]="helloworld";
int ret=write(fd,caBuf,sizeof(caBuf));
if(ret==-1)
{
printf("write error:%s\n",strerror(errno));
}
else
{
printf("write %d bytes to file\n",ret);
}
close(fd);
}
//helloworldhelloworldhelloworld
pwrite
#include <stdio.h>
#include <unistd.h> //write() read() sleep()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
int fd=-1;
//当打开一个文件时,读写位置默认在文件首部
fd=open(argv[1],O_RDWR | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP);
if(-1 == fd)
{
printf("open error:%s\n",strerror(errno));
return -1;
}
//偏移参照位置
//文件首部,当前位置,文件尾
//返回值为距离文件首的偏移量
//第一个参数:文件描述符
//第二个参数:相对参照位置的偏移量
// 当偏移为正数时,往参照位置后偏移
// 当偏移为负数时,往参照位置前偏移
//第三个参数:参照位置SEEK_SET
//第三个参数:参照位置
off_t offset = lseek(fd,0,SEEK_END);//返回值为距离文件头的偏移量
if(-1==offset)
{
printf("lseek error:%s\n",strerror(errno));
}
else
{
printf("file size:%ld\n",offset);
}
//档一个程序存在多个运行分支的时候,并且每个运行分支都有可能操作文件时存在以下问题:
//当A分支使用lseek设置读写位置完成时,
//A分支的运行暂停,B分支开始运行,并且B分支对文件进行了读写操作,从而改变了A分支设置的读写位置
//当B分支运行暂停.A分支重新接着往后运行时,若A分支要对文件进行读写,那么读写的位置并不是之前设置的位置,而是B分支运行后的读写位置,从而得不到预期结果
//原子操作:操作部分,要么都执行,要么都不执行
//问题解决方案:将A分支的的lseek和之后的读写操作合成原子操作
// 1.将操作部分使用锁,锁住,合成原子操作
// 2.调用pread()或者pwrite()函数来完成操作
/*lseek(fd,-5,SEEK_END);
write(fd,"666",3);*/
char *pData="Hello World";
ssize_t size=pwrite(fd,pData,strlen(pData),5);
if(-1==size)
{
printf("pwrite error:%s\n",strerror(errno));
}
close(fd);
return 0;
}
//原来为:1234567890
//现在为:12345Hello World
fsync
#include <stdio.h>
#include <unistd.h> //write() read() sleep()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*sync()
syncfs()
fsync()
*/
int myOpen(const char *pathname)
{
int fd = -1;
if (NULL != pathname)
{
fd = open(pathname, O_WRONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd)
{
printf("open error: %s\n", strerror(errno));
}
}
return fd;
}
int main()
{
int fd = -1;
fd = myOpen("test.data");
if (-1 != fd)
{
char *pData="Hello World";
write(fd, pData, strlen(pData));
//将缓冲区的
int ret=fsync(fd);
if(-1==ret)
{
printf("fsync error:%s\n",strerror(errno));
}
close(fd);
}
return 0;
}
//Hello World
pread
#include <stdio.h>
#include <unistd.h> //write() read() sleep()
#include <errno.h> //errno
#include <string.h> //strerror()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
int fd=-1;
//当打开一个文件时,读写位置默认在文件首部
fd=open(argv[1],O_RDWR | O_CREAT,S_IRUSR | S_IWUSR | S_IRGRP);
if(-1 == fd)
{
printf("open error:%s\n",strerror(errno));
return -1;
}
//偏移参照位置
//文件首部,当前位置,文件尾
//返回值为距离文件首的偏移量
//第一个参数:文件描述符
//第二个参数:相对参照位置的偏移量
// 当偏移为正数时,往参照位置后偏移
// 当偏移为负数时,往参照位置前偏移
//第三个参数:参照位置SEEK_SET
//第三个参数:参照位置
off_t offset = lseek(fd,0,SEEK_END);//返回值为距离文件头的偏移量
if(-1==offset)
{
printf("lseek error:%s\n",strerror(errno));
}
else
{
printf("file size:%ld\n",offset);
}
//档一个程序存在多个运行分支的时候,并且每个运行分支都有可能操作文件时存在以下问题:
//当A分支使用lseek设置读写位置完成时,
//A分支的运行暂停,B分支开始运行,并且B分支对文件进行了读写操作,从而改变了A分支设置的读写位置
//当B分支运行暂停.A分支重新接着往后运行时,若A分支要对文件进行读写,那么读写的位置并不是之前设置的位置,而是B分支运行后的读写位置,从而得不到预期结果
//原子操作:操作部分,要么都执行,要么都不执行
//问题解决方案:将A分支的的lseek和之后的读写操作合成原子操作
// 方法1.将操作部分使用锁,锁住,合成原子操作
// 方法2.调用pread()或者pwrite()函数来完成操作
//pread()/pwrite():偏移到距离文件首部n字节的地方进行读写操作
char *pData="Hello World";
//第四个参数:从文件首部开始的偏移量
//第三个参数:要写入的字节数
ssize_t size=pwrite(fd,pData,strlen(pData),5);
if(-1==size)
{
printf("pwrite error:%s\n",strerror(errno));
}
char caBuf[32]={'\0'};
size=pread(fd,caBuf,3,3);
if(-1!=size)
{
printf("%s\n",caBuf);
}
close(fd);
return 0;
}
//12345Hello World