我有一些代码使用低级别的i/o read和write系统调用,如C编程语言书籍Kernighan和Ritchie的第170页所述.功能原型就是这样
int n_read = read ( int fd, char *buf, int n )
int n_read = write ( int fd, char *buf, int n )
Run Code Online (Sandbox Code Playgroud)
现在使用这些两个.c文件read,并write通过一个更大的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 ) );
}
Run Code Online (Sandbox Code Playgroud)
而较大的基于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
Run Code Online (Sandbox Code Playgroud)
正如您可能已经猜到的,这适用于小于2 ^ 31的nbyte值.我需要读取超过2 GB的数据,因此我需要nbyte为fortran中的长整数和INTEGER*8.
有没有等效的read64和write64,就像unistd.h和features.h提供的lseek64一样?
重新编码的最佳方法是什么?我应该使用fread和fwrite吗?是int fd从低级别write一样FILE *stream的fread()?
我的要求是能够传递一个8字节的长整数,以允许最大100到500千兆字节的值或一个12位数的整数,这是nbyte的值
难道我得到什么或者目前使用失去了read和write其标识为"系统调用"?这是什么意思?
编辑:你不能,至少不能在Linux上.read永远不会传输超过32位整数可以容纳的值.
从Linux的联机帮助页read:
在Linux上,read()(和类似的系统调用)最多将传输0x7ffff000(2,147,479,552)个字节,返回实际传输的字节数.(在32位和64位系统上都是如此.)
这不是POSIX的约束,它是POSIX所允许的,但最终它的实现定义了read行为方式.正如Andrew Hanle所报道的那样,读取32GB文件在Solaris上运行得很好.在这种情况下,我的旧答案仍然有效.
旧答案:
read可以使用64位文件就好了.它的定义<unistd.h>如下: -
ssize_t read(int fd, void *buf, size_t count);
Run Code Online (Sandbox Code Playgroud)
您必须调整您的例程才能使用size_t而不是int正确支持大文件.
在使用大文件之前,您应该检查SSIZE_MAX(支持的最大值count),read如果它是小的(或拆分成较小的块),则应该中止.SSIZE_MAX是实现定义的值.