open()函数

openresty 记录返回值 open的返回值_偏移量

  1. open函数返回的是int类型,成功返回的是int类型的文件描述符,失败返回-1
  2. 文件路径是个char*指针
  3. 打开方式比较常用的是O_RDONLY,O_WRONLY,O_TRUNC

read()函数

位于<unistd.h>中,原型:ssize_t read(int fd,void*buf,size_t count)
返回的是成功读取的长度,如果在调read之前已到达文件末尾,则这次read返回0,-1为失败

  1. fd为int类型的文件描述符,一般都是用一个open函数的返回;
  2. 指针类型的buf,是read的缓存buffer,读到的内容放在buffer中
  3. count是要读多少个字节的数据

write()函数

位于<unistd.h>中,原型:ssize_t write(int fd,void*buf,size_t count)
返回的是成功写入的长度

  1. fd同上,是要被写入的文件的文件描述符
  2. buf是write缓存的buffer,将buffer中的内容写入fd对应的文件中
  3. 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;
}