【问题标题】:How do I read from a non-text file in c (linux)?如何从 c (linux) 中的非文本文件中读取?
【发布时间】:2013-04-16 20:20:47
【问题描述】:

我正在尝试通过 UDP 套接字发送文件(一次一个块)。它适用于 .txt 文件,但是当我尝试从 .jpg/.rar 读取时,即使文件大于 2mb,它也只能读取几个字节(比我“要求”的要少)。

我尝试使用 open/pread(我也尝试使用 lseek 和 read)和 fopen(二进制模式)/fread/fseek,我得到了相同的结果(即对于 2mb .jpg 文件,我得到这个输出“读取10 从偏移量 0")。 请告诉我我做错了什么。

这是负责从文件中读取块的代码:

void * work(void * p){
...
int psize=100;
int file;
//FILE *file;

//open the file
file=open(wArg.req.fileName, O_RDONLY);
//file=fopen(wArg.req.fileName, "rb");

//read the file chunk from the offset
buff=(void *) malloc(psize);
n=pread(file, buff, psize, wArg.req.offset);
//fseek(file,wArg.req.offset, SEEK_SET);
//fread(buff, 1, psize, file);
if(n<0){
    perror("read");
    exit(1);
}

printf("read %d from offset %d\n", (int)strlen(buff),wArg.req.offset);

n=sendto(wArg.sock, buff, psize, 0, (struct sockaddr*)&caddr, sizeof(struct sockaddr_in));
printf("sent %d\n", (int)strlen(buff));


close(file); 
//fclose(file);
...
}

【问题讨论】:

  • 请务必检查malloc 返回的值是否有效。 buff 可能由于内存不足而无法分配。
  • 什么是pread()?如果您始终使用 gcc 标志 -Wall -Werror,您的生活会变得更轻松。

标签: c linux


【解决方案1】:

二进制文件可以包含NULL-bytes,strlen 将在找到这样的NULL-byte 后停止计数。使用pread 的返回值找出buffer 的大小。

所有str* 函数都需要C 字符串,它必须NULL-byte 结尾,并且不能将它们放在“中间”。

【讨论】:

    【解决方案2】:

    您不能使用strlen (buff),因为buff 是二进制数据。当您执行pread 时,您在n 中捕获的返回值包含读取的字节数。您应该在sendto 中使用它而不是psize

    【讨论】:

      【解决方案3】:

      pread() 从文件描述符文件中偏移偏移量(从文件开头)读取最多 count 个字节到缓冲区中,从 buf 开始。文件偏移量没有改变。 由于它是一个二进制文件,所以 strlen 不能在这里工作...... 所以使用 pread 并初始化 psize 以返回 pread() 的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多