The f_lseek function moves the file read/write pointer of an open file object. It can also be used to increase the file size (cluster pre-allocation).
FRESULT f_lseek ( FIL* FileObject, /* Pointer to the file object structure */ DWORD Offset /* File offset in unit of byte */ );
The f_lseek function moves the file read/write pointer of an open file. The offset can be specified in only origin from top of the file. When an offset above the file size is specified in write mode, the file size is increased to the offset and the data in the expanded area is undefined. This is suitable to create a large file quickly, for fast write operation. After the f_lseek function succeeded, current read/write pointer should be checked in order to make sure the read/write pointer has been moved correctry. In case of the current read/write pointer is not the expected value, either of followings has been occured.
Fast seek feature is enabled when _USE_FASTSEEK is set to 1 and the member cltbl in the file object is not NULL. This feature enables fast backward/long seek operations without FAT access by cluster link map table (CLMT) stored in the user defined table. It is also applied to f_read/f_write functions. In this mode, the file size cannot be increased by f_write/f_lseek functions.
The CLMT must be created in the user defined DWORD array prior to use fast seek feature. To create the CLMT, set pointer to the DWORD array to the member cltbl in the file object, set the array size in unit of items into the first item and call the f_lseek function with Offset = CREATE_LINKMAP. After the function succeeded and CLMT is created, no FAT access is occured in subsequent f_read/f_write/f_lseek functions to the file. If the function failed with FR_NOT_ENOUGH_CORE, the given array size is insufficient for the file and the required items is returned into the first item of the array. The required array size is (number of fragments + 1) * 2 items. For example, when the file is fragmented in 5, 12 items will be required for the CLMT.
Available when _FS_MINIMIZE <= 2.
/* Open file */ file = malloc(sizeof (FIL)); if (!file) ... res = f_open(file, "file.dat", FA_READ|FA_WRITE); if (res) ... /* Move to offset of 5000 from top of the file */ res = f_lseek(file, 5000); /* Move to end of the file to append data */ res = f_lseek(file, f_size(file)); /* Forward 3000 bytes */ res = f_lseek(file, f_tell(file) + 3000); /* Rewind 2000 bytes (take care on overflow) */ res = f_lseek(file, f_tell(file) - 2000);
/* Cluster pre-allocation (to prevent buffer overrun on streaming write) */ res = f_open(file, recfile, FA_CREATE_NEW | FA_WRITE); /* Create a file */ res = f_lseek(file, PRE_SIZE); /* Expand file size (cluster pre-allocation) */ if (res || f_tell(file) != PRE_SIZE) ... /* Check if the file has been expanded */ res = f_lseek(file, DATA_START); /* Record data stream WITHOUT cluster allocation delay */ ... /* DATA_START and write block size should be aligned to sector boundary */ res = f_truncate(file); /* Truncate unused area */ res = f_lseek(file, 0); /* Put file header */ ... res = f_close(file);
/* Using fast seek feature */ DWORD lktbl[SZ_TBL]; /* Link map table buffer */ res = f_lseek(file, ofs1); /* This is normal seek (file.cltbl is nulled on file open) */ file.cltbl = lktbl; /* Enable fast seek feature */ lktbl = SZ_TBL; /* Set table size */ res = f_lseek(file, CREATE_LINKMAP); /* Create CLMT */ ... res = f_lseek(file, ofs2); /* This is fast seek (file.cltbl != NULL) */