Windows de 32 bits e o limite de tamanho de arquivo de 2 GB (C com fseek e ftell)
Estou tentando portar um pequeno programa de análise de dados de um UNIX de 64 bits para um sistema Windows XP de 32 bits (não pergunte :)). Mas agora estou tendo problemas com o limite de tamanho de arquivo de 2 GB (há muito tempo não sendo 64 bits nesta plataforma).
Pesquisei neste site e em outros por possíveis soluções, mas não consigo encontrar nenhuma que seja diretamente traduzível para o meu problema. O problema está no uso de fseek e ftell.
Alguém sabe de uma modificação nas duas funções a seguir para fazê-las funcionar no Windows XP de 32 bits para arquivos maiores que 2 GB (na verdade, solicite 100 GB).
É vital que o tipo de retorno de nsamples seja um número inteiro de 64 bits (possivelmente 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;
}
e
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);
}
Tentei usar _fseeki64 e _ftelli64 usando o seguinte para substituir nsamples:
__int64 nsamples(char* filename)
{
FILE *fp;
__int64 n;
int result;
/* Open file */
fp = fopen(filename, "rb");
if (fp == NULL)
{
perror("Er,ror: 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;
}
para um arquivo de4815060992 bytes eu recebo260046848 amostras (por exemplo,_ftelli64
dá520093696 bytes) o que é estranho.
Curiosamente, quando deixo de fora o(__int64)
transmitir na chamada para_fseeki64
Eu recebo um erro de tempo de execução (argumento inválido).
Alguma ideia?