O_APPEND//追加(在文件后面写)
=======================================================
复制mp3
#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>
#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 to %s\\n", ret, argv[2]);
}
}
return 0;
}
=======================================================
偏移量
#include <stdio.h>
#include <errno.h> //errno
#include <string.h> //strerror()
//lseek()
#include <unistd.h> //read() write()
/*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_RDONLY | O_CREAT
, S_IRUSR | S_IWUSR | S_IRGRP );
if (-1 == fd)
{
return -1;
}
//偏移参照位置:
// 文件首部,当前位置,文件尾
//返回值为距离文件首的偏移量
//第一个参数:文件描述符
//第二个参数:相对参照位置的偏移量
当偏移量为正数时,往参照物位置后偏移
当偏移量为负数时,往参照物位置前偏移
//第三个参数:参照位置
off_t offset =lseek(fd,0,SEEK_END);
if(-1==offset)
{
printf("sleek error: %s\\n", strerror(errno));
}
else
{
printf("file size: %ld\\n", offset);
}
return 0;
}
=======================================================
lseek(设置读写位置)
#include <stdio.h>
#include <errno.h> //errno
#include <string.h> //strerror()
/*lseek()*/
#include <sys/types.h>
#include <unistd.h> //read() write()
/*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,SEEK_CUR,SEEK_END
off_t offset = lseek(fd, 0, SEEK_END);
if (-1 == offset)
{
printf("lseek error:%s\\n", strerror(errno));
return -1;
}
else
{
printf("file size: %ld\\n", offset);
}
//将读写位置偏移到距离文件首部10字节的地方
offset = lseek(fd, 10, SEEK_SET);
printf("offset = %ld\\n", offset);
char *pData = "888";
//写入数据时
//会将以读写位置开始的strlen(pData)个字节的数据
//用新写入的数据覆盖掉
write(fd, pData, strlen(pData));
//将读写位置从当前位置往后偏移5字节
lseek(fd, 5, SEEK_CUR);
write(fd, "666", 3);
//当成功读写n个字节时,
//读写位置会从没有发生读写前的位置
//开始往后偏移n个字节
//每次读写文件时,都是从当前的读写位置开始读写
close(fd);
return 0;
}
pwrite,pread(当一个程序存在多个运行分支)
#include <stdio.h>
#include <errno.h> //errno
#include <string.h> //strerror()
/*lseek()*/
#include <sys/types.h>
#include <unistd.h> //read() write()
/*open()*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//运行方式:./可执行文件名 要进行读取操作的文件名
// ---> ./autoOpe test.data
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;
}
//当一个程序存在多个运行分支,
//并且每个运行分支都有可能操作文件时,
//存在以下问题:
// 当A分支使用lseek设置读写位置完成时,
// A分支的运行暂停,B分支开始运行,并且B分支对
// 文件进行了读写操作,从而改变了A分支设这的读写位置
// 当B分支运行暂停,A分支重新接着往后运行时
// 若A分支要对文件进行读写,
// 那么读写的位置并不是之前设置的位置,
// 而是B分支运行后的读写位置
// 从而得不到预期结果
//原子操作:操作部分,要么都执行,要么都不执行
//问题解决方案:
// 将A分支的lseek和之后的读写操作合成原子操作
// 方法1, 将操作部分使用锁,锁住,合成原子操作
// 方法2, 调用pread() 或者 pwrite()函数来完成操作
#if 0
lseek(fd, -5, SEEK_END);
write(fd, "666", 3);
#endif
//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, 4, 3);
if (-1 != size)
{
printf("%s\\n", caBuf);
}
close(fd);
return 0;
}
运行结果:
test.data里的字符
运行后的结果:(从偏移量为3的位置开始读取4个字节)
write(写入数组stu[6])
#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
, 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, "zhaoliu", 'f', 99}
, {1005, "xiaoqi", 'm', 79}
, {1006, "laoba", 'm', 89}};
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;
}
read(读出1,3,6位置的字符)
#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;
void showStuInfo(const Student *pStu)
{
if (NULL != pStu)
{
printf("id:%d, name:%s, sex:%c, score:%.1f\\n"
, pStu->iId, pStu->caName
, pStu->cSex, pStu->fScore);
}
}
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;
Student stu;
//将Student对象的空间都设置为'\\0'
memset(&stu, '\\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if (-1 != ret)
{
showStuInfo(&stu);
}
off_t offset = lseek(fd, sizeof(Student), SEEK_CUR);
if (-1 != offset)
{
memset(&stu, '\\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if (-1 != ret)
{
showStuInfo(&stu);
}
}
offset = lseek(fd, 2*sizeof(Student), SEEK_CUR);
if (-1 != offset)
{
memset(&stu, '\\0', sizeof(Student));
ret = read(fd, &stu, sizeof(Student));
if (-1 != ret)
{
showStuInfo(&stu);
}
}
close(fd);
}
return 0;
}