Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
how to preallocate/resize file

Subject: how to preallocate/resize file

From: rych

Date: 15 Dec, 2008 17:52:01

Message: 1 of 4

I'd like to preallocate a large disk space for a file that I'm then
going to memory-map and write part by part. In C I can use a run-time
function like _chsize_s to do it instantaneously. But I can't figure a
way to do it in Matlab. Writing a huge zeros vector, I could go out of
memory. Writing a block by block in a for loop, until the file gets
resized to a required size, -- this doesn't sound elegant at all.
Igor

Subject: how to preallocate/resize file

From: James Tursa

Date: 16 Dec, 2008 11:03:02

Message: 2 of 4

rych <rychphd@gmail.com> wrote in message <76c761cf-5089-4efb-a897-07119331947f@v5g2000prm.googlegroups.com>...
> I'd like to preallocate a large disk space for a file that I'm then
> going to memory-map and write part by part. In C I can use a run-time
> function like _chsize_s to do it instantaneously. But I can't figure a
> way to do it in Matlab. Writing a huge zeros vector, I could go out of
> memory. Writing a block by block in a for loop, until the file gets
> resized to a required size, -- this doesn't sound elegant at all.
> Igor

Since you want the exact functionality of the _chsize_s routine in C, you could just write a mex file to do this using that function. It was simple enough, so I wrote it below. It has a reasonable amount of input error checking, but I did not include a check for huge requested filesize values. That would be something you might want to add. If you are not familiar with mex files, simply place this file somewhere on your MATLAB path, call it some name like preallocatefile.c, set your default directory to that directory, and then do this at the MATLAB prompt:

mex -setup
(then pick your Microsoft C/C++ compiler)
mex preallocatefile.c

Now you have a function that takes two inputs, filename and filesize, and preallocates the file to that size. e.g., at the MATLAB prompt:

preallocatefile("myfile",1024)

would create a 1K file.

James Tursa

----------------------------------------------------------------

// A MATLAB mex function to preallocate (or reallocate/truncate)
// a file to a requested size.
//
// Inputs:
// 1st input: Char string file name
// 2nd input: Requested file size in bytes (any numeric class)
//
// Outputs:
// (none)
//
// Programmer: James Tursa

#include <stdio.h>
#include <io.h>
#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    char *filename;
    __int64 filesize;
    FILE *fp;
    errno_t errno;
    
    if( nrhs != 2 ) {
        mexErrMsgTxt("Need exactly two inputs: filename, size");
    }
    if( nlhs != 0 ) {
        mexErrMsgTxt("There are no outputs allowed");
    }
    if( !mxIsChar(prhs[0]) ) {
        mexErrMsgTxt("1st input must be filename char string");
    }
    if( !mxIsNumeric(prhs[1]) || mxGetNumberOfElements(prhs[1]) != 1 ) {
        mexErrMsgTxt("2nd input must be numeric scalar file size");
    }
    filename = mxArrayToString(prhs[0]);
    filesize = mxGetScalar(prhs[1]);
    if( filesize < 0 ) {
        mexErrMsgTxt("2nd input must be non-negative");
    }
    fp = fopen( filename, "w" );
    mxFree(filename);
    if( fp == NULL ) {
        mexErrMsgTxt("Unable to open file");
    }
    errno = _chsize_s( _fileno(fp), filesize );
    fclose(fp);
    if( errno != 0 ) {
        mexErrMsgTxt("Unable to set size of file");
    }
}

Subject: how to preallocate/resize file

From: rych

Date: 16 Dec, 2008 18:09:46

Message: 3 of 4

On Dec 16, 11:03=A0am, "James Tursa" <aclassyguywithakno...@hotmail.com>
wrote:
> rych <rych...@gmail.com> wrote in message <76c761cf-5089-4efb-a897-071193=
319...@v5g2000prm.googlegroups.com>...
> > I'd like to preallocate a large disk space for a file that I'm then
> > going to memory-map and write part by part. In C I can use a run-time
> > function like _chsize_s to do it instantaneously. But I can't figure a
> > way to do it in Matlab. Writing a huge zeros vector, I could go out of
> > memory. Writing a block by block in a for loop, until the file gets
> > resized to a required size, =A0-- this doesn't sound elegant at all.
> > Igor
>
> Since you want the exact functionality of the _chsize_s routine in C, you=
 could just write a mex file to do this using that function. It was simple =
enough, so I wrote it below. It has a reasonable amount of input error chec=
king, but I did not include a check for huge requested filesize values. Tha=
t would be something you might want to add. If you are not familiar with me=
x files, simply place this file somewhere on your MATLAB path, call it some=
 name like preallocatefile.c, set your default directory to that directory,=
 and then do this at the MATLAB prompt:
>
> mex -setup
> (then pick your Microsoft C/C++ compiler)
> mex preallocatefile.c
>
> Now you have a function that takes two inputs, filename and filesize, and=
 preallocates the file to that size. e.g., at the MATLAB prompt:
>
> preallocatefile("myfile",1024)
>
> would create a 1K file.
>
> James Tursa
>
> ----------------------------------------------------------------
>
> // A MATLAB mex function to preallocate (or reallocate/truncate)
> // a file to a requested size.
> //
> // Inputs:
> // =A0 =A0 1st input: Char string file name
> // =A0 =A0 2nd input: Requested file size in bytes (any numeric class)
> //
> // Outputs:
> // =A0 =A0 (none)
> //
> // Programmer: James Tursa
>
> #include <stdio.h>
> #include <io.h>
> #include "mex.h"
>
> void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs=
[])
> {
> =A0 =A0 char *filename;
> =A0 =A0 __int64 filesize;
> =A0 =A0 FILE *fp;
> =A0 =A0 errno_t errno;
>
> =A0 =A0 if( nrhs !=3D 2 ) {
> =A0 =A0 =A0 =A0 mexErrMsgTxt("Need exactly two inputs: filename, size");
> =A0 =A0 }
> =A0 =A0 if( nlhs !=3D 0 ) {
> =A0 =A0 =A0 =A0 mexErrMsgTxt("There are no outputs allowed");
> =A0 =A0 }
> =A0 =A0 if( !mxIsChar(prhs[0]) ) {
> =A0 =A0 =A0 =A0 mexErrMsgTxt("1st input must be filename char string");
> =A0 =A0 }
> =A0 =A0 if( !mxIsNumeric(prhs[1]) || mxGetNumberOfElements(prhs[1]) !=3D =
1 ) {
> =A0 =A0 =A0 =A0 mexErrMsgTxt("2nd input must be numeric scalar file size"=
);
> =A0 =A0 }
> =A0 =A0 filename =3D mxArrayToString(prhs[0]);
> =A0 =A0 filesize =3D mxGetScalar(prhs[1]);
> =A0 =A0 if( filesize < 0 ) {
> =A0 =A0 =A0 =A0 mexErrMsgTxt("2nd input must be non-negative");
> =A0 =A0 }
> =A0 =A0 fp =3D fopen( filename, "w" );
> =A0 =A0 mxFree(filename);
> =A0 =A0 if( fp =3D=3D NULL ) {
> =A0 =A0 =A0 =A0 mexErrMsgTxt("Unable to open file");
> =A0 =A0 }
> =A0 =A0 errno =3D _chsize_s( _fileno(fp), filesize );
> =A0 =A0 fclose(fp);
> =A0 =A0 if( errno !=3D 0 ) {
> =A0 =A0 =A0 =A0 mexErrMsgTxt("Unable to set size of file");
> =A0 =A0 }
>
> }

Thank you James, you're very kind. I'm going to try and compile your
mex file then.

Subject: how to preallocate/resize file

From: Oliver Woodford

Date: 24 Oct, 2013 15:57:11

Message: 4 of 4

rych wrote:
> I'd like to preallocate a large disk space for a file that I'm then
> going to memory-map and write part by part. In C I can use a run-time
> function like _chsize_s to do it instantaneously. But I can't figure a
> way to do it in Matlab. Writing a huge zeros vector, I could go out of
> memory. Writing a block by block in a for loop, until the file gets
> resized to a required size, -- this doesn't sound elegant at all.
> Igor

This works:

% Create the file
fh = javaObject('java.io.RandomAccessFile', 'test.dat', 'rw');
% Allocate the right amount of space
fh.setLength(1024);
% Close the file
fh.close();

Oliver

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us