2017-05-31 72 views
0

我想写一个简单的程序,通过封装函数如open,lseek,pread读取文件。尝试从文件读取使用文件描述符打印数字和斜线到控制台

我的测试文件中包含:

first second third forth fifth sixth 
seventh eighth 

我试图主函数读取20个字节,从文件偏移10:

#include <iostream> 
#include "CacheFS.h" 
using namespace std; 
int main(int argc, const char * argv[]) { 
    char * filename1 = "/Users/Desktop/File"; 
    int fd1 = CacheFS_open(filename1); 
    //read from file and print it 
    void* buf[20]; 
    CacheFS_pread(fd1, &buf, 20, 10); 
    cout << (char*)buf << endl; 
} 

实施的,主要是使用功能:

int CacheFS_open(const char *pathname) 
{ 
    mode_t modes = O_SYNC | 0 | O_RDONLY; 
    int fd = open(pathname, modes); 
    return fd; 
} 

int CacheFS_pread(int file_id, void *buf, size_t count, off_t offset) 
{ 
    off_t seek = lseek(file_id, offset, SEEK_SET); 
    off_t fileLength = lseek(file_id, 0, SEEK_END); 
    if (count + seek <= fileLength) //this case we are not getting to the file end when readin this chunk 
    { 
     pread(file_id, &buf, count, seek); 
    } else { //count is too big so we can only read a part of the chunk 
     off_t size = fileLength - seek; 
     pread(file_id, &buf, size, seek); 
    } 
    return 0; 
} 

我的主要功能打印到控制台:

\350\366\277_\377 

我期望它从文件本身打印一些值,而不是一些数字和斜杠代表我不了解的东西。 这是为什么发生?

回答

1

下列变化会使你的工作方案:

  1. 你的缓冲区必须是一个存在的字符数组,你的CacheFS_pread函数被调用,而不地址操作&然后。同样使用buffer size minus 1,因为pread函数将覆盖终止\0,因为它只读取了n个字节的文件。我在这里使用一个零初始化的char数组,至少在最后会有一个空终止\0

    char buf[20] = { '\0' }; // declare and initialize with zeros 
    CacheFS_pread(fd1, buf, sizeof(buf) - 1, 10); 
    
  2. 您的函数头应该只接受一个字符指针,用于类型安全的原因。

    int CacheFS_pread(int file_id, char* buf, size_t count, off_t offset) 
    
  3. 你PREAD呼叫则没有地址运算符&

    pread(file_id, buf, count, seek); 
    

输出:​​因为缓冲区仅20!

另外我会检查你的计算和你的if语句是否正确。我觉得这不完全正确。我也会推荐使用pread的返回值。

+0

我实现了你在3中写的(从buf调用读取中删除&),它工作。我采取的其他点作为额外的有用的提示。谢谢!! – Eyzuky

+0

缓冲区需要在堆栈或堆上存在。 'pread'函数将不会为你分配它。如果您忽略写入堆栈或堆损坏后不想写入的位置。 –

+0

我将按照你的说明实现初始化,谢谢先生。 – Eyzuky

相关问题