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;
}
11.PNG
=======================================================
偏移量
#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;
}
//偏移參照位置:
// 文件首部映穗,當前位置,文件尾
//返回值為距離文件首的偏移量
//第一個參數(shù):文件描述符
//第二個參數(shù):相對參照位置的偏移量
當偏移量為正數(shù)時她肯,往參照物位置后偏移
當偏移量為負數(shù)時,往參照物位置前偏移
//第三個參數(shù):參照位置
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;
}
2.PNG
=======================================================
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;
}
//偏移參照位置:
// 文件首部拐迁,當前位置胸私,文件尾
//返回值為距離文件首的偏移量
//第一個參數(shù):文件描述符
//第二個參數(shù):相對參照位置的偏移量
// 當偏移量為正數(shù)時挫掏,往參照位置后偏移
// 當偏移量為負數(shù)時措伐,往參照位置前偏移
//第三個參數(shù):參照位置 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字節(jié)的地方
offset = lseek(fd, 10, SEEK_SET);
printf("offset = %ld\\n", offset);
char *pData = "888";
//寫入數(shù)據(jù)時
//會將以讀寫位置開始的strlen(pData)個字節(jié)的數(shù)據(jù)
//用新寫入的數(shù)據(jù)覆蓋掉
write(fd, pData, strlen(pData));
//將讀寫位置從當前位置往后偏移5字節(jié)
lseek(fd, 5, SEEK_CUR);
write(fd, "666", 3);
//當成功讀寫n個字節(jié)時特纤,
//讀寫位置會從沒有發(fā)生讀寫前的位置
//開始往后偏移n個字節(jié)
//每次讀寫文件時,都是從當前的讀寫位置開始讀寫
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>
//運行方式:./可執(zhí)行文件名 要進行讀取操作的文件名
// ---> ./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分支運行后的讀寫位置
// 從而得不到預期結果
//原子操作:操作部分狈网,要么都執(zhí)行宙搬,要么都不執(zhí)行
//問題解決方案:
// 將A分支的lseek和之后的讀寫操作合成原子操作
// 方法1, 將操作部分使用鎖,鎖住孙援,合成原子操作
// 方法2, 調用pread() 或者 pwrite()函數(shù)來完成操作
#if 0
lseek(fd, -5, SEEK_END);
write(fd, "666", 3);
#endif
//pread()/pwrite():
// 偏移到距離文件首部n字節(jié)的地方進行讀寫操作
char *pData = "Hello World";
//第四個參數(shù):從文件首部開始的偏移量
//第三個參數(shù):要寫入的字節(jié)數(shù)
ssize_t size = pwrite(fd, pData, strlen(pData), 5);
if (-1 == size)
{
printf("pwrite error:%s\\n", strerror(errno));
}
char caBuf[32] = {'\\0'};
//第四個參數(shù):從文件首部開始的偏移量
//第三個參數(shù):要讀取的字節(jié)數(shù)
size = pread(fd, caBuf, 4, 3);
if (-1 != size)
{
printf("%s\\n", caBuf);
}
close(fd);
return 0;
}
運行結果:
test.data里的字符
2.PNG
運行后的結果:(從偏移量為3的位置開始讀取4個字節(jié))
1.PNG
write(寫入數(shù)組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;
}
3.PNG