繁体   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