2017-09-22 108 views
0

我正在實施ftp,我想上傳和下載文件,當我下載或上傳PDF文件時,它們已損壞。如何處理讀取任何文件,使用read()write()mmap?下面是我嘗試過的簡化代碼。讀取和寫入pdf或二進制數據在C

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 

int  is_regular_file(const char *path) 
{ 
    struct stat path_stat; 

    stat(path, &path_stat); 
    return (S_ISREG(path_stat.st_mode)); 
} 

int  ft_get_file_size(const char *filename) 
{ 
    struct stat file; 
    int   fd; 

    if (!is_regular_file(filename)) 
     return (-1); 
    fd = open(filename, O_RDONLY); 
    memset(&file, 0, sizeof(struct stat)); 
    fstat(fd, &file); 
    close(fd); 
    return (file.st_size); 
} 

char *read_file(const char *filename) 
{ 
    char *content; 
    int  file_size; 
    int  fd; 
    ssize_t retval; 

    if ((file_size = ft_get_file_size(filename)) <= 0) 
     return (NULL); 
    content = (char *)malloc(sizeof(char) * file_size + 1); 
    fd = open(filename, O_RDONLY); 
    retval = read(fd, content, file_size); 
    content[retval + 1] = '\0'; 
    close(fd); 
    return (content); 
} 

void write_file(char *file, char *content) 
{ 
    int fd; 

    fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); 
    if (fd) 
     write(fd, content, strlen(content)); 
    close(fd); 
} 

int main() { 
    char *test = read_file("ftp.en.pdf"); 
    write_file("copy.pdf", test); 
    return EXIT_SUCCESS; 
} 

下載和上傳文件時,從文件讀取的所有數據,然後將數據發送到插座的過程。我試過使用mmap,我仍然收到損壞的文件。

文件已損壞的錯誤消息

Corrupted file

+0

有書面幾個問題你的代碼。 'read()'和'write()'返回'ssize_t',而不是'int'。 'struct stat'的'st_size'元素是'off_t',也不是'int'。 'fd = open(...);如果(fd)...'也是錯誤的。 open()在失敗時返回「-1」,計算結果爲true。你也不要檢查'read()'和'write()'的返回值,以確保調用實際讀或寫你請求的每個字節。 –

+0

通常,當調用'read()'或'write()'時,需要在循環中調用它們,使用數據位置的滑動窗口,直到讀取或寫入所有數據。調用'malloc()'時調用 – user3629249

+0

,1)返回的類型是'void *',它可以被分配給任何指針。鑄造只是混淆了代碼,使其更難以理解,調試等。建議刪除演員陣容。 2)表達式'sizeof(char)'在C標準中定義爲1.將任何東西乘以1都不起作用。建議刪除該表達式。 3)總是檢查(!= NULL)返回的值以確保操作成功。在main()中使用 – user3629249

回答

4

爲二進制數據可以有\0字符,你不能把你的內容作爲一個字符串,所以strlen(content)是錯誤的。您必須返回您的read_file函數的內容大小。

例如,將您的函數定義爲char *read_file(const char *filename, int *size)並返回大小*size。同樣地定義你寫的功能void write_file(char *file, char *content, int size)

(並忘記了的malloc +1)