open()函数
- open函数返回的是int类型,成功返回的是int类型的文件描述符,失败返回-1
- 文件路径是个char*指针
- 打开方式比较常用的是O_RDONLY,O_WRONLY,O_TRUNC
read()函数
位于<unistd.h>中,原型:ssize_t read(int fd,void*buf,size_t count)
返回的是成功读取的长度,如果在调read之前已到达文件末尾,则这次read返回0,-1为失败
- fd为int类型的文件描述符,一般都是用一个open函数的返回;
- 指针类型的buf,是read的缓存buffer,读到的内容放在buffer中
- count是要读多少个字节的数据
write()函数
位于<unistd.h>中,原型:ssize_t write(int fd,void*buf,size_t count)
返回的是成功写入的长度
- fd同上,是要被写入的文件的文件描述符
- buf是write缓存的buffer,将buffer中的内容写入fd对应的文件中
- count是将buffer中多少个字节的内容写入到fd文件中
sprintf()函数
sprintf()和printf()的作用很类似,都可以打印数据,但是sprintf更强悍,可以将打印出来的内容写入buffer中;
int sprintf( char *buffer, const char *format [, argument] … );
用法如:
char *who = "I";
char *whom = "you";
sprintf(s, "%s love %s.", who, whom); // 产生:"I love you. "
lseek()函数
在一篇博客是看到这样获取文件长度的方法:
int length = lseek(fd,0,SEEK_END);
我想实现的目标是从一个文件读length长度的内容到buffer,再将buffer中的length长度的内容写到另一个文件;但是像上面这样使用了lseek函数之后,被写入的文件一直都是奇怪的符号:^@…;
而^@这个符号是‘\0’的显示,原来我初始化buffer的时候都是用的0,而ASCII码=0对应着的是’\0’,后面一看原来使用的read的函数返回的是0,说明啥也没读到。
这是为什么呢??
原来lseek函数的作用是将fd对应的文件的内部偏移置为想要的位置,返回的是修改后当前的偏移位置;既然将偏移置为末尾了,那么read的时候当然什么都读不到了;
off_t lseek(int fd, off_t offset, int whence)
offset 指定了一个以字节为单位的数值
whence 表明应参照哪个基点来解释offset参数,应为下列其中之一:
SEEK_SET 将文件偏移量设置为文件头部起始点开始的offset字节
SEEK_CUR 相对于当前文件偏移量,将文件偏移量调整offset个字节
SEEK_END 将文件偏移量设置为起始于文件尾部的offset个字节,也就是offset应该从文件最后一个字节之后的下一个字节算起。
#############################################################################
这里要解释下size_t,来自百度百科:
在C++中,设计size_t 就是为了适应多个平台的。size_t的引入增强了程序在不同平台上的可移植性。size_t是针对系统定制的一种数据类型,一般是整型,因为C/C++标准只定义一最低的位数,而不是必需的固定位数。而且在内存里,对数的高位对齐存储还是低位对齐存储各系统都不一样。为了提高代码的可移植性,就有必要定义这样的数据类型。一般这种类型都会定义到它具体占几位内存等。当然,有些是编译器或系统已经给定义好的。经测试发现,在32位系统中size_t是4字节的,而在64位系统中,size_t是8字节的,这样利用该类型可以增强程序的可移植性。
上个实践代码(对randbyte_check的修改版):
#include <stdio.h>
#include <stdlib.h> /* exit */
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <malloc.h>
#define File1 "/mnt/file_read"
#define File2 "/mnt/file_write"
int open_file(char *file_name, int flags)
{
int fd;
char retstr[100] = {0};
fd = open(file_name, flags);
if (fd == -1) {
strcpy(retstr, "Failed to open: ");
strcat(retstr, file_name);
perror(retstr);
exit(-1);
}
return fd;
}
int main(int argc, char **argv)
{
int fd1, fd2, ret;
fd1 = open_file(File1, O_RDONLY);
fd2 = open_file(File2, O_WRONLY|O_TRUNC);
int length = lseek(fd1,0,SEEK_END);
lseek(fd1,0,SEEK_SET);
//必须要用这个lseek回到SEEK_SET也就是起始的位置,不然偏移在文件末尾SEEK_END
char *result = (char*)malloc(sizeof(char)*length);
char *res_str = (char*)malloc(sizeof(char)*length);
ret = read(fd1, result, length);
if (ret > sizeof(unsigned char)*length) {
if (ret < 0)
perror("Error Reading: ");
else if (ret < sizeof(unsigned char))
printf("Error Reading: too few bytes! %d < %ld\n",
ret, sizeof(unsigned char));
else
printf("Error Reading: too many bytes! %d > %ld\n",
ret, sizeof(unsigned char));
exit(-1);
}
sprintf(res_str, "%s",result);
ret = write(fd2, res_str, length);
if (ret == -1) {
perror("Error Writing: ");
exit(-1);
}
close(fd1);
close(fd2);
return ret;
}