c - UNIX 读取行为

标签 c linux unix

我编写了这段小代码来确定读取行为。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>

int main ()
{
  ssize_t ret;
  int fd;
  char str[30] = {0};
  off_t lret

  fd = open("./sample", O_RDWR);
  printf("File descriptor = %d\n",fd);

  lret = lseek(fd,LONG_MAX,SEEK_SET);
  printf("%ld\n",lseek(fd, 0, SEEK_CUR));

  ret = read(fd, str, 20);
  if (ret == -1) {
     perror("read error");
  }
  else {
     printf("%ld\n",ret);
     printf("%s\n",str);
  }

  ret = write(fd, "bye", 3);
  if (ret == -1) {
     perror("write error");
  }
  else
     printf("%ld\n",ret);

  printf("%ld\n",lseek(fd, 0, SEEK_CUR));
  close (fd);

  return 0;
}

这是输出:

$ cat sample
HELLO$ ./a.out
File descriptor = 3
4294967295
read error: Invalid argument
write error: Invalid argument
4294967295
$ ll sample
-rw-r--r--. 1 bruce stud 5 Jan 14 17:25 sample

但是如果我将 lseek 语句更改为

ret = lseek(fd,5,SEEK_SET);

读取返回0

$ ./a.out
File descriptor = 3
5
0

3
8
$ cat sample
HELLObye$ ll sample
-rw-r--r--. 1 bruce stud 8 Jan 14 17:26 sample

为什么读取会这样?

最佳答案

请注意,lseek 返回的值是 off_t,而不是 size_t。不同之处在于 off_t 有符号。当您取一个有符号值并将其设为无符号时,它看起来像一个很大的正数。

我预计“LONG_MAX”实际上不是 4294967295,而是 2147483647 (2^31-1) 或更大的数字。所以 4294967295 来自 -1 [它是 2^32-1,这确实与 32 位数学中的 -1 相同]。

换句话说,您从 lseek 收到错误。

关于c - UNIX 读取行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14327953/

相关文章:

c - 内存映射文件的大小不断增大

c - 想学c应该用什么软件

c - 指向嵌套结构的指针

linux - Grep:与 -e 和 -o 选项一起使用

c - 使用冒泡排序对链表进行排序

c++ - 我应该如何在 C++(在 ubuntu 上)中获取 "localhost"的完全限定域名?

java - 执行java类时无法在linux服务器中添加jar

linux - Grep 在 x 毫秒内查找字符串中的值

java - Windows 上的 "lo"接口(interface)等效项是什么

linux - rsync 仅同步当天文件