Pim*_*art 5 c windows porting c99 large-files
我试图将一个小型数据分析程序从64位UNIX移植到32位Windows XP系统(不要问:)).但是现在我遇到了2GB文件大小限制的问题(在这个平台上长时间不是64位).
我搜索了这个网站和其他人可能的解决方案,但找不到任何可以直接翻译我的问题.问题在于使用fseek和ftell.
有没有人知道对以下两个函数的修改,使它们可以在32位Windows XP上运行大于2GB的文件(实际上是100GB).
至关重要的是,nsamples的返回类型是64位整数(可能是int64_t).
long nsamples(char* filename)
{
FILE *fp;
long n;
/* Open file */
fp = fopen(filename, "rb");
/* Find end of file */
fseek(fp, 0L, SEEK_END);
/* Get number of samples */
n = ftell(fp) / sizeof(short);
/* Close file */
fclose(fp);
/* Return number of samples in file */
return n;
}
Run Code Online (Sandbox Code Playgroud)
和
void readdata(char* filename, short* data, long start, int n)
{
FILE *fp;
/* Open file */
fp = fopen(filename, "rb");
/* Skip to correct position */
fseek(fp, start * sizeof(short), SEEK_SET);
/* Read data */
fread(data, sizeof(short), n, fp);
/* Close file */
fclose(fp);
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用_fseeki64和_ftelli64使用以下代码替换nsamples:
__int64 nsamples(char* filename)
{
FILE *fp;
__int64 n;
int result;
/* Open file */
fp = fopen(filename, "rb");
if (fp == NULL)
{
perror("Error: could not open file!\n");
return -1;
}
/* Find end of file */
result = _fseeki64(fp, (__int64)0, SEEK_END);
if (result)
{
perror("Error: fseek failed!\n");
return result;
}
/* Get number of samples */
n = _ftelli64(fp) / sizeof(short);
printf("%I64d\n", n);
/* Close file */
fclose(fp);
/* Return number of samples in file */
return n;
}
Run Code Online (Sandbox Code Playgroud)
对于4815060992字节的文件,我得到260046848个样本(例如_ftelli64给出520093696字节),这很奇怪.
奇怪的是,当我(__int64)在调用中省略演员时,_fseeki64我得到一个运行时错误(无效的参数).
有任何想法吗?
很抱歉没有早点发布,但我已经有一段时间专注于其他项目了。以下解决方案有效:
__int64 nsamples(char* filename)
{
int fh;
__int64 n;
/* Open file */
fh = _open( filename, _O_BINARY );
/* Find end of file */
n = _lseeki64(fh, 0, SEEK_END);
/* Close file */
_close(fh);
return n / sizeof(short);
}
Run Code Online (Sandbox Code Playgroud)
诀窍是使用_open而不是fopen打开文件。我仍然不明白为什么必须这样做,但至少现在可以了。感谢大家的建议,最终为我指明了正确的方向。