Charles E Campbell Jr wrote:
I've attached a patch to vim 7.1 which extends getfsize()
As I've mentioned, I think further testing will be needed before patching Vim for 64-bit file lengths. Here is a possible interim workaround to allow Dr.Chip's LargeFile.vim script to accurately detect large files on many platforms. Attached is a tiny C program to build a tool called filemeg. Example usage: filemeg /path/to/file gives output: 42 which means that the specified file is 42 megabytes (actually, any value from 42 to nearly 43). I was going to work out how to adapt the LargeFile script to use this tool, if the user sets an option to invoke it. But it's taking too long because I don't know enough about Vim, so I'm just presenting the tool at this stage. People may like to check how filemeg works on various systems and report back. I have tried it on files over 4GB on Fedora Core 6 and Windows XP (x86-32 platform). Putting something like this inside Vim would be a bit of a nightmare IMHO because of the extraordinary range of supported compilers, operating systems and hardware. Adapting LargeFile.vim to work with filemeg: - Compile the source and test running at command line. - Put the executable in your path (better: in a Vim directory which the script could invoke somehow). - Set a new script option to use filemeg. - The script BufReadPre would call a new script function. - That function would check the file size with: let result = system('filemeg /path/to/file') - If result is a number, it is the file size in megabytes. - Otherwise, result is "Error..." and the script should treat the file as large (or maybe not...). I've attached the C source, and included it below for those who don't mind a little wrapping. John /* Output length of specified file in megabytes. * John Beckett 2007/05/25 * For Linux with LFS (large file support), and Win32. * * Output is suitable for reading by a script. * Output is always one line. * If any problem occurs, line starts with "Error". * Otherwise, line is the size of the specified file in megabytes. * Size is a truncated integer (file of 3.9MB would give result "3"). * The size won't overflow a 32-bit signed integer ("Error" if it does). * If argument is a directory, result is "0" (done by stat64()). */ #if defined(__linux) # define _LARGEFILE64_SOURCE #elif defined(_WIN32) # define off64_t __int64 # define stat64 _stati64 #endif #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc, char *argv[]) { off64_t size, overflowmask; struct stat64 sb; if ( argc != 2 ) { puts("Error: Need path of file to report its size in megabytes."); return 1; } if ( stat64(argv[1], &sb) != 0 ) { puts("Error: Could not get file information."); return 1; } size = sb.st_size >> 20; /* 2^20 = 1 meg */ overflowmask = 0x7fffffff; /* ensure 64-bit calculation */ if ( (size & ~overflowmask) != 0 ) {puts("Error: File size in megabytes overflows 32-bit signed integer.");
return 1; } printf("%d\n", (int)size); return 0; }
filemeg.c
Description: Binary data