2017-05-31 73 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

相關問題