簡體   English   中英

從C中的二進制文件讀取

[英]reading from a binary file in C

我目前在一個項目中,我必須從二進制文件中讀取並通過套接字發送,而在嘗試發送整個文件時遇到了困難。

到目前為止,這是我寫的內容:

        FILE *f = fopen(line,"rt");
        //size = lseek(f, 0, SEEK_END)+1;
        fseek(f, 0L, SEEK_END);
        int size = ftell(f);
        unsigned char buffer[MSGSIZE];
        FILE *file = fopen(line,"rb");
        while(fgets(buffer,MSGSIZE,file)){
            sprintf(r.payload,"%s",buffer);
            r.len = strlen(r.payload)+1;
            res = send_message(&r);
            if (res < 0) {
                perror("[RECEIVER] Send ACK error. Exiting.\n");
                return -1;
            }   
        }

我認為這與我讀入的緩沖區大小有關,但我不知道它的正確公式是什么。

還有一件事,sprintf是否正確完成?

如果您正在讀取二進制文件,則NUL字符可能會出現在文件中的任何位置。

因此,使用像sprintfstrlen這樣的字符串函數是一個壞主意。 如果確實需要使用第二個緩沖區( buffer ),則可以使用memcpy 您也可以直接讀入r.payload(如果r.payload已經分配了足夠的大小)。

您正在尋找二進制文件的fread fread的返回值告訴您已將多少字節讀取到緩沖區中。

您也可以考慮再次致電fseek 請參閱此處如何獲取C語言的文件大小?

也許您的代碼可能如下所示:

#include <stdint.h>
#include <stdio.h>

#define MSGSIZE 512

struct r_t {
  uint8_t payload[MSGSIZE];
  int len;
};

int send_message(struct r_t *t);

int main() {
  struct r_t r;
  FILE *f = fopen("test.bin","rb");
  fseek(f, 0L, SEEK_END);
  size_t size = ftell(f);
  fseek(f, 0L, SEEK_SET);
  do {
    r.len = fread(r.payload, 1, sizeof(r.payload), f);
    if (r.len > 0) {
      int res = send_message(&r);
      if (res < 0) {
        perror("[RECEIVER] Send ACK error. Exiting.\n");
        fclose(f);
        return -1;
      }
    }   
  } while (r.len > 0);
  fclose(f);
  return 0;
}

不,sprintf沒有正確完成。 緩沖區溢出很容易發生,這是一個非常嚴重的安全問題。

我將考慮以例如1024字節的塊而不是逐行發送文件,因此我將fgets調用替換為fread調用。

為什么要兩次打開文件? 顯然是要獲取其大小,但是您只能打開一次,然后跳回到文件的開頭。 而且,您沒有將讀取的尺寸用於任何事情。

它是二進制文件還是文本文件? fgets()假定您正在讀取文本文件-它在換行符處停止-但您說這是一個二進制文件,並用“ rb”打開(實際上,第一次使用“ rt”打開它那是一個錯字)。

IMO,您永遠不要使用sprintf。 寫入緩沖區的字符數取決於傳入的參數,在這種情況下,如果緩沖區中沒有'\\ 0',則無法預測將多少字節復制到r.payload,並且有一個您很有可能會溢出該緩沖區。

我認為sprintf()是第一要解決的問題。 使用memcpy(),您可以准確地告訴它要復制多少字節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM