title: 32 bit Windows and the 2GB file size limit (C with fseek and ftell)
body: <p>I am attempting to port a small data analysis program from a 64 bit UNIX to a 32 bit Windows XP system (don't ask :)).
  But now I am having problems with the 2GB file size limit (long not being 64 bit on this platform).</p>
  
  <p>I have searched this website and others for possible sollutions but cannot find any that are directly translatable to my problem.
  The problem is in the use of fseek and ftell.</p>
  
  <p>Does anyone know of a modification to the following two functions to make them work on 32 bit Windows XP for files larger than 2GB (actually order 100GB).</p>
  
  <p>It is vital that the return type of nsamples is a 64 bit integer (possibly int64_t).</p>
  
  <pre><code>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;
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>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);
  }
  </code></pre>
  
  <p>I tried using _fseeki64 and _ftelli64 using the following to replace nsamples:</p>
  
  <pre><code>__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;
  }
  </code></pre>
  
  <p>for a file of <strong>4815060992 bytes</strong> I get <strong>260046848</strong> samples (e.g. <code>_ftelli64</code> gives <strong>520093696</strong> bytes) which is strange.</p>
  
  <p>Curiously when I leave out the <code>(__int64)</code> cast in the call to <code>_fseeki64</code> I get a runtime error (invalid argument).</p>
  
  <p>Any ideas?</p>