C低级读写功能是64位等效吗?

时间:2016-04-13 19:05:43

标签: c

我有一些代码使用低级别的i / o readwrite系统调用,如C编程语言书籍Kernighan和Ritchie的第170页所述。 函数原型是这个

int n_read = read  ( int fd, char *buf, int n )
int n_read = write ( int fd, char *buf, int n )

现在使用这些readwrite的两个.c文件被更大的基于fortran的程序调用,以读取和写入大量数据。

C代码就是这样,没有任何类型的#include,在函数名后跟下划线并通过引用传递:

int read_ ( int *descriptor, char *buffer, int *nbyte )
{
   return ( read( *descriptor, buffer, *nbyte ) );
}

int write_ ( int *descriptor, char *buffer, int *nbyte )
{
   return ( write( *descriptor, buffer, *nbyte ) );
}

而较大的基于fortran的程序会做这样的事情

INTEGER nbyte
COMPLEX*16 matrix(*)
INTEGER READ, WRITE
EXTERNAL READ, WRITE

status = READ( fd, matrix, nbyte )
if ( status .eq. -1 ) then
   CALL ERROR('C call read failure')
   stop
endif

正如您可能已经猜到的,这适用于 nbyte 小于2 ^ 31的值。我需要读取超过2 GB的数据,因此我需要 nbyte 在fortran中成为长整数 INTEGER * 8

有没有等效的read64和write64,就像unistd.h和features.h提供的lseek64一样?

重新编码的最佳方法是什么? 我应该使用fread和fwrite吗? 来自int fd的{​​{1}}与write的{​​{1}}相同?

我的要求是能够传递一个8字节的长整数,以允许最大100到500千兆字节的值或一个12位数的整数,这是 nbyte 的值

目前使用FILE *streamfread()标识为“系统调用”,我获得了什么或输了?这是什么意思?

2 个答案:

答案 0 :(得分:5)

编辑:您不能,至少不在Linux上。 <{1}}永远不会传输超过32位整数可以容纳的内容。

read上的Linux联机帮助页:

  

在Linux上,read()(以及类似的系统调用)最多将传输          0x7ffff000(2,147,479,552)个字节,返回字节数          实际转移。 (32位和64位都是如此          系统。)

这不是POSIX的约束,它是POSIX所允许的,但最终它的实现定义了read的行为方式。正如Andrew Hanle报告的那样,读取32GB文件在Solaris上运行正常。在这种情况下,我的旧答案仍然有效。

旧答案:

read可以正常使用64位文件。它在read中的定义如下: -

<unistd.h>

您必须调整例程才能使用ssize_t read(int fd, void *buf, size_t count); 代替size_t,以便正确支持大文件。

在将int与大文件一起使用之前,您应该检查SSIZE_MAXcount支持的最大值),如果它是小的,则应中止(或拆分为较小的块)。 read是实现定义的值。

答案 1 :(得分:0)

正如@Leandros所观察到的,符合POSIX的read()write()实现接受size_t类型的字节计数,并返回类型为ssize_t的字节计数。这些可能是实际适用于您的定义,因为C标准未指定read()write()函数。然而,这并没有太大区别,因为size_t不需要比int更宽 - 事实上,它可以更窄。

你无论如何都有更大的问题。 Fortran代码似乎假设它正在调用的C函数将读取/写入指定的完整字节数,否则会失败,但POSIX read()write()在成功时无法保证这样做。实际上,前几天存在一个问题,这个问题取决于这样的事实:这些函数一次不能传输更多的字节,而不是一个有符号的32位整数,即使在64位系统上也是如此。位[s]size_t

通过将read_()write_()函数实现到循环,执行对基础read()的连续调用,可以一举杀死这两只鸟write()函数,直到传输完整数量的指定字节或发生错误。