C 读取二进制文件到缓冲区

C Read binary file to a buffer

我正在尝试创建一个简单的 VM,它可以读取二进制文件,遵循二进制文件中的指令(每条指令 4 个字 - 32 位),然后在遵循所有指令后输出结果。

我目前正处于项目的第一阶段,我正在尝试使用 fread/fopen 将我的文件内容读入缓冲区。在大多数情况下,代码类似于 fread for cplusplus.com 上给出的示例,但是我想找到一种方法将我的文件一次分成 4 个单词。我以前从未在如此低的水平上工作过,并且在确定我是否正确执行此操作时遇到问题,并希望这里有人可以帮助我确保我将文件正确分解为 4 个单词。

FILE * pFile;
long lSize;
unsigned char * buffer;
size_t result;

  pFile = fopen ( "test.bin" , "rb" );

  if (pFile==NULL) {fprint("error, file null")}

  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

  // allocate memory to contain the whole file:
  buffer = (unsigned char*) malloc (sizeof(unsigned char)*lSize);
  if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

  // copy the file into the buffer:
  result = fread (buffer, 4,lSize,pFile); //The error is here, if I use 1 instead of 4 there is no error output but I am not sure this would properly break the file into 4 words read at a time.
  if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
   printf("%ld\n",lSize);

现在,当我 运行 出现此错误时,除非我将我评论的行中的数字更改回 1。

将二进制文件表示为缓冲区是您的 OS 可以为您做的事情; mmap 的手册页在 C89 中有一个工作示例(所以它是古董):

       fd = open(argv[1], O_RDONLY);

...

       if (fstat(fd, &sb) == -1)           /* To obtain file size */
           handle_error("fstat");

       offset = atoi(argv[2]);
       pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
           /* offset for mmap() must be page aligned */

...

       if (argc == 4) {
           length = atoi(argv[3]);
           if (offset + length > sb.st_size)
               length = sb.st_size - offset;
                   /* Can't display bytes past end of file */

       } else {    /* No length arg ==> display to end of file */
           length = sb.st_size - offset;
       }

       addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
                   MAP_PRIVATE, fd, pa_offset);
       if (addr == MAP_FAILED)
           handle_error("mmap");

现在,addr 指向包含进程地址 space 中输入文件的内存区域。

这将节省您在开始处理之前阅读整个文件的时间,因为您的 OS 可以自动只读取您实际访问的文件部分,而无需进一步的麻烦。

此外,由于您正在编写 VM(无论这对您意味着什么!),您应该了解典型的进程内存结构,因此学习 mmap 的作用是一个很好的练习。