在c语言中读取缓冲区块中未知长度的文件

在c语言中读取缓冲区块中未知长度的文件,c,C,我正在尝试将未知长度的二进制文件读入缓冲区块,而不使用诸如lseek(),fseek之类的函数 我使用了一次有1024个字节的结构缓冲区。当读取大于1012字节的文件时,它将分配几个缓冲区。但是,当它遇到最后一个块时,它肯定会少于或等于1024字节。 因此,我试图计算最后一个块的长度,这样我就可以一直读取最后一个块,直到eof,但我对如何实现这一点感到困惑 提前谢谢 #include <stdio.h> #include <stdlib.h> typedef struc

我正在尝试将未知长度的二进制文件读入缓冲区块,而不使用诸如
lseek()
fseek
之类的函数

  • 我使用了一次有1024个字节的结构缓冲区。当读取大于1012字节的文件时,它将分配几个缓冲区。但是,当它遇到最后一个块时,它肯定会少于或等于1024字节。 因此,我试图计算最后一个块的长度,这样我就可以一直读取最后一个块,直到
    eof
    ,但我对如何实现这一点感到困惑 提前谢谢

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct Buffer{
      unsigned char data[1012];
      struct Buffer *next; //12 bytes
    }Buffer;
    
    void mymemcpy(void *dest, void *src, size_t length){
      Buffer *buffer_toFill = (Buffer *)dest;
      Buffer *buffer_toAdd = (Buffer *)src;
      int a = 0; 
      for(int i = 0; i < length; i++){
        buffer_toFill->data[i] = buffer_toAdd->data[i];
      }
    }
    
    Buffer* add_buffer_front(Buffer *head, Buffer *read_buffer, int size){
      Buffer *new_buffer = malloc(sizeof(Buffer));
      mymemcpy(new_buffer, read_buffer, size);
      if(head != NULL){
        new_buffer->next = head;
      }
      return new_buffer;
    }
    
    void display_List(Buffer *head, size_t length){
      Buffer *current = head;
      while(current != NULL){
        for(int i = 0; i < length; i++){
          printf("%02X",(unsigned)current->data[i]); //this shows different value compare with  xxd <filename>
          //printf("%c", current->data[i]);  
        }
        Buffer *prev = current;
        free(prev);
        current = current->next;
      }
    }
    
    int main(int argc, char **argv){
      FILE *fd;
      Buffer *head_buffer = NULL;
      int file_length = 0;
      int eof_int = 1;
      if(argc != 2){
        printf("Usage: readFile <filename>\n");
        return 1; 
      }
    
      fd = fopen(argv[1], "rb");
    
      while(eof_int != 0){ 
        Buffer *new_buffer = malloc(sizeof(Buffer));
        eof_int = fread(new_buffer, sizeof(Buffer)-12, 1, fd);
        if(eof_int == 0){ 
          //size_t length
          //
          //
          head_buffer = add_buffer_front(head_buffer, new_buffer, length);
          file_length += length;
        }else{
          head_buffer = add_buffer_front(head_buffer, new_buffer, (sizeof(new_buffer->data)));
          file_length += (sizeof(new_buffer->data));
        }
      }
      display_List(head_buffer, file_length);
      fclose(fd);
      return 0;
    }
    
    #包括
    #包括
    类型定义结构缓冲区{
    无符号字符数据[1012];
    结构缓冲区*next;//12字节
    }缓冲器;
    void mymemcpy(void*dest、void*src、大小和长度){
    缓冲区*缓冲区\豆腐渣=(缓冲区*)目的地;
    Buffer*Buffer_toAdd=(Buffer*)src;
    int a=0;
    for(int i=0;i数据[i]=缓冲区\豆腐渣->数据[i];
    }
    }
    缓冲区*添加缓冲区\前端(缓冲区*头部,缓冲区*读取缓冲区,整数大小){
    Buffer*new_Buffer=malloc(sizeof(Buffer));
    mymemcpy(新缓冲区、读缓冲区、大小);
    if(head!=NULL){
    新建缓冲区->下一步=头部;
    }
    返回新的缓冲区;
    }
    无效显示列表(缓冲区*头、大小\u t长度){
    缓冲器*电流=磁头;
    while(当前!=NULL){
    for(int i=0;idata[i]);//这显示与xxd不同的值
    //printf(“%c”,当前->数据[i]);
    }
    缓冲区*prev=当前;
    免费(上);
    当前=当前->下一步;
    }
    }
    int main(int argc,字符**argv){
    文件*fd;
    Buffer*head\u Buffer=NULL;
    int file_length=0;
    int-eof_int=1;
    如果(argc!=2){
    printf(“用法:readFile\n”);
    返回1;
    }
    fd=fopen(argv[1],“rb”);
    而(eof_int!=0){
    Buffer*new_Buffer=malloc(sizeof(Buffer));
    eof_int=fread(新的_缓冲区,大小eof(缓冲区)-12,1,fd);
    如果(eof_int==0){
    //尺寸和长度
    //
    //
    head\u buffer=添加\u buffer\u front(head\u buffer,new\u buffer,length);
    文件长度+=长度;
    }否则{
    head_buffer=添加_buffer_front(head_buffer,new_buffer,sizeof(new_buffer->data));
    文件长度+=(sizeof(新的缓冲区->数据));
    }
    }
    显示列表(头缓冲区、文件长度);
    fclose(fd);
    返回0;
    }
    
    您有几个问题

    (1)
    fread
    返回读取的项目数,但不会返回
    eof
    指示。您需要调用
    feof(stream*)
    以确定是否已到达文件末尾

    (2) 您的下一个指针是12字节。这是一个非常危险的假设。更愿意读取分配给数据结构的1012字节。很可能您当前正在打印未读入但只是未初始化内存的内容


    (3)使用<代码> FADAD 的返回值来决定要复制多少内存。

    < P>请参阅下面代码中的注释-也考虑更改1012以使用一个y*定义。
    #包括
    #包括
    类型定义结构缓冲区{
    无符号字符数据[1012];
    结构缓冲区*next;//12字节
    }缓冲器;
    //创建一个存储文件内容的结构
    类型定义结构{
    缓冲器*磁头;
    缓冲器*尾部;
    尺寸与长度;
    }我的文件;
    /*
    void mymemcpy(void*dest、void*src、大小和长度){
    缓冲区*缓冲区\豆腐渣=(缓冲区*)目的地;
    Buffer*Buffer_toAdd=(Buffer*)src;
    int a=0;
    for(int i=0;i数据[i]=缓冲区\豆腐渣->数据[i];
    }
    }
    缓冲区*添加缓冲区\前端(缓冲区*头部,缓冲区*读取缓冲区,整数大小){
    Buffer*new_Buffer=malloc(sizeof(Buffer));
    mymemcpy(新缓冲区、读缓冲区、大小);
    if(head!=NULL){
    新建缓冲区->下一步=头部;
    }
    返回新的缓冲区;
    }
    */
    //让我们更容易些——缓冲区已经“malloced”过一次了——为什么还要再做一次
    //你为什么要撤销文件
    //或许
    void add_buffer(要添加的缓冲区*,MyFile*文件,大小\u t额外长度){
    如果(file->tail){//列表中有一项
    文件->尾部->下一步=待添加;
    }否则{//第一个缓冲区!
    文件->头=待添加;
    文件->尾部=待添加;
    }
    要添加->下一个=NULL;//这是最后一个,所以总是这样
    文件->长度+=额外长度;
    }
    /*
    无效显示列表(缓冲区*头、大小\u t长度){
    缓冲器*电流=磁头;
    while(当前!=NULL){
    for(int i=0;idata[i]);//这显示与xxd不同的值
    //printf(“%c”,当前->数据[i]);
    }
    缓冲区*prev=当前;
    免费(上);
    当前=当前->下一步;
    }
    }
    */
    //而是通过新的结构
    无效显示列表(MyFile*文件){
    size\u t contents\u left=文件->长度;
    缓冲区*当前=文件->头部;
    while(当前){
    //每个区块最多有1012个字节-检查一下
    size\u t chunk\u length=contents\u left>1012?1012:contents\u left;
    对于(int i=0;i数据[i]);
    }
    当前=当前->下一步;
    }
    }
    }
    int main(int argc,字符**argv){
    文件*fd;
    MyFile读取文件;
    read_file.head=NULL;
    read_file.tail=NULL;
    read_file.length=0;
    Buffer*head\u Buffer=NULL;
    int file_length=0;
    int-eof_int=1;
    如果(argc!=2){
    printf(“用法:readFile\n”);
    返回1;
    }
    fd=fopen(argv[1],“rb”);
    //检查fd
    如果(fd==NULL){
    //错误材料
    return EXIT_FAILURE;//查找此文件的include
    }
    而(eof_int!=0){
    Buffer*new_Buffer=malloc(sizeof(Buffer));
    eof_int=fread(new_buffer->data,1012,1,fd);//不要假设指针的大小并将其存储在正确的位置
    如果(eof_int==0){//不读取任何内容
    free(new_buffer);//我们太乐观了!最终不需要这个
    打破
    }否则{
    添加缓冲区(&read\u文件、new\u缓冲区、eof\u int);
    }
    }
    显示\u列表(&读取\u文件);
    fclose(fd);
    返回0;
    }
    
    你要找的诀窍是
    fr
    
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct Buffer{
      unsigned char data[1012];
      struct Buffer *next; //12 bytes
    }Buffer;
    
    // Create a structure to store stuff about a file
    
    typedef struct {
       Buffer *head;
       Buffer *tail;
       size_t length;
    } MyFile;
    
    /*
    void mymemcpy(void *dest, void *src, size_t length){
      Buffer *buffer_toFill = (Buffer *)dest;
      Buffer *buffer_toAdd = (Buffer *)src;
      int a = 0; 
      for(int i = 0; i < length; i++){
        buffer_toFill->data[i] = buffer_toAdd->data[i];
      }
    }
    
    Buffer* add_buffer_front(Buffer *head, Buffer *read_buffer, int size){
      Buffer *new_buffer = malloc(sizeof(Buffer));
      mymemcpy(new_buffer, read_buffer, size);
      if(head != NULL){
        new_buffer->next = head;
      }
      return new_buffer;
    }
    
    */
    
    // Lets make this easier - The buffer has already been "malloced" once - why do it again
    
    // And why are you reversing the file
    
    // Perhaps 
    
    void add_buffer(Buffer *to_be_added, MyFile *file, size_t extra_length) {
       if (file->tail) { // We have one item in the list
         file->tail->next = to_be_added;
       } else { // First buffer!
         file-> head = to_be_added;
         file-> tail = to_be_added;
       }
       to_be_added->next = NULL;  // This is always the case as it is the last one
       file->length += extra_length;
    }
    
    /*
    void display_List(Buffer *head, size_t length){
      Buffer *current = head;
      while(current != NULL){
        for(int i = 0; i < length; i++){
          printf("%02X",(unsigned)current->data[i]); //this shows different value compare with  xxd <filename>
          //printf("%c", current->data[i]);  
        }
        Buffer *prev = current;
        free(prev);
        current = current->next;
      }
    }
    
    */
    
    // Instead pass in the new structure
    
    void display_list(MyFile *file) {
       size_t contents_left = file -> length;
       Buffer * current = file -> head;
       while (current) {
          // At most each chunk has 1012 bytes - Check for that
          size_t chunk_length = contents_left > 1012 ? 1012 : contents_left;
           for(int i = 0; i <chunk_length ; i++){
             printf("%02X",(unsigned)current->data[i]);
           }
           current = current -> next;
       }
    }
    
    
    }
    int main(int argc, char **argv){
      FILE *fd;
      MyFile read_file;
      read_file.head = NULL;
      read_file.tail = NULL;
      read_file.length = 0;
    
      Buffer *head_buffer = NULL;
      int file_length = 0;
      int eof_int = 1;
      if(argc != 2){
        printf("Usage: readFile <filename>\n");
        return 1; 
      }
    
      fd = fopen(argv[1], "rb");
    
      // Check fd
      if (fd == NULL) {
        // error stuff
        return EXIT_FAILURE; // Look up the include for this
     }
      while(eof_int != 0){ 
        Buffer *new_buffer = malloc(sizeof(Buffer));
        eof_int = fread(new_buffer->data, 1012, 1, fd); // Do not make assumptions on the size of a pointer and store it in the correct location
        if(eof_int == 0) { // Read nothing
           free(new_buffer); // We was too optimistic! Did Not need this in the end 
           break;
        } else {
          add_buffer(&read_file, new_buffer, eof_int);
        }
      }
      display_List(&read_file);
      fclose(fd);
      return 0;
    }
    
    size_t bytes_read = fread(buffer, 1, sizeof(Buffer)-12, fd);
    
    const size_t BUFFER_SIZE = 1024;
    
    typedef struct Buffer {
        // I'll explain why I switched to a pointer in a moment
        unsigned char *data;
        size_t size;
        struct Buffer *next;
    } Buffer;
    
    void Buffer_print( Buffer *buffer ) {
        for( size_t i = 0; i < buffer->size; i++ ) {
            printf("%02hhX ", buffer->data[i]);
        }
    }
    
    Buffer *Buffer_new() {
        Buffer *buffer = malloc(sizeof(Buffer));
    
        buffer->size = 0;
        buffer->data = NULL;
        buffer->next = NULL;
    
        return buffer;
    }
    
    size_t Buffer_read( Buffer *buffer, size_t buffer_size, FILE* fp ) {
        buffer->data = malloc(buffer_size);
        size_t bytes_read = fread(buffer->data, 1, buffer_size, fp);
        buffer->size = bytes_read;
        return bytes_read;
    }
    
    while( Buffer_read( buffer, BUFFER_SIZE, fp ) > 0 ) {
        ... now what ...
    }
    fclose(fp);
    
    Buffer *Buffer_push( Buffer *tail, Buffer *new_tail ) {
        tail->next = new_tail;
        return new_tail;
    }
    
    Buffer *head = Buffer_new();
    Buffer *tail = head;
    while( Buffer_read( tail, BUFFER_SIZE, fp ) > 0 ) {
        tail = Buffer_push( tail, Buffer_new() );
    }
    fclose(fp);
    
    void Buffer_print_all( Buffer *head ) {
        for( Buffer *buffer = head; buffer != NULL; buffer = buffer->next ) {
            Buffer_print(buffer);
        }
    }
    
    Buffer_print_all(head);