📄 fat32_filelib.c
字号:
// Take into account partial sector read
if ((count+offset) % 512)
totalSectors++;
bytesRead = 0;
for (i=0;i<totalSectors;i++)
{
// Read sector of file
if ( FAT32_SectorReader(file->startcluster, (sector+i)) )
{
// Read length - full sector or remainder
if ( (bytesRead+512) > count )
thisReadCount = count - bytesRead;
else
thisReadCount = 512;
// Copy to file buffer (for continuation reads)
memcpy(file->filebuf, FATFS_Internal.currentsector, 512);
file->currentBlock = (sector+i);
// Copy to application buffer
// Non aligned start
if ( (i==0) && (offset!=0) )
memcpy( (BYTE*)(buffer+bytesRead), (BYTE*)(file->filebuf+offset), thisReadCount);
else
memcpy( (BYTE*)(buffer+bytesRead), file->filebuf, thisReadCount);
bytesRead+=thisReadCount;
file->bytenum+=thisReadCount;
if (thisReadCount>=count)
return bytesRead;
}
// Read failed - out of range (probably)
else
{
return (int)bytesRead;
}
}
return bytesRead;
}
//-----------------------------------------------------------------------------
// fl_fseek: Seek to a specific place in the file
// TODO: This should support -ve numbers with SEEK END and SEEK CUR
//-----------------------------------------------------------------------------
int fl_fseek( FL_FILE *file , UINT32 offset , int origin )
{
// If first call to library, initialise
CHECK_FL_INIT();
if (file==NULL)
return -1;
// Check if file open
if (file->inUse==FALSE)
return -1;
if ( (origin == SEEK_END) && (offset!=0) )
return -1;
// Invalidate file buffer
file->currentBlock = 0xFFFFFFFF;
if (origin==SEEK_SET)
{
file->bytenum = offset;
if (file->bytenum>file->filelength)
file->bytenum = file->filelength;
return 0;
}
else if (origin==SEEK_CUR)
{
file->bytenum+= offset;
if (file->bytenum>file->filelength)
file->bytenum = file->filelength;
return 0;
}
else if (origin==SEEK_END)
{
file->bytenum = file->filelength;
return 0;
}
else
return -1;
}
//-----------------------------------------------------------------------------
// fl_fgetpos: Get the current file position
//-----------------------------------------------------------------------------
int fl_fgetpos(FL_FILE *file , UINT32 * position)
{
if (file==NULL)
return -1;
// Check if file open
if (file->inUse==FALSE)
return -1;
// Get position
*position = file->bytenum;
return 0;
}
//-----------------------------------------------------------------------------
// _create_file: Create a new file
//-----------------------------------------------------------------------------
#ifdef INCLUDE_WRITE_SUPPORT
static FL_FILE* _create_file(char *filename, UINT32 size)
{
FL_FILE* file;
FAT32_ShortEntry sfEntry;
char shortFilename[11];
int tailNum;
// If first call to library, initialise
CHECK_FL_INIT();
file = _find_spare_file();
if (file==NULL)
return NULL;
// Clear filename
memset(file->path, '\n', sizeof(file->path));
memset(file->filename, '\n', sizeof(file->filename));
// Split full path into filename and directory path
FileString_SplitPath(filename, file->path, file->filename);
// Check if file already open
if (_check_file_open(file))
return FALSE;
// If file is in the root dir
if (file->path[0]==0)
{
file->parentcluster = FAT32_GetRootCluster();
file->inRoot = TRUE;
}
else
{
file->inRoot = FALSE;
// Find parent directory start cluster
if (!_open_directory(file->path, &file->parentcluster))
return NULL;
}
// Check if same filename exists in directory
if (FAT32_GetFileEntry(file->parentcluster, file->filename,&sfEntry)==TRUE)
return NULL;
// Create the file space for the file
file->startcluster = 0;
file->filelength = size;
if (!FAT32_AllocateFreeSpace(TRUE, &file->startcluster, (file->filelength==0)?1:file->filelength))
return NULL;
// Generate a short filename & tail
tailNum = 0;
do
{
// Create a standard short filename (without tail)
FATMisc_CreateSFN(shortFilename, file->filename);
// If second hit or more, generate a ~n tail
if (tailNum!=0)
FATMisc_GenerateTail((char*)file->shortfilename, shortFilename, tailNum);
// Try with no tail if first entry
else
memcpy(file->shortfilename, shortFilename, 11);
// Check if entry exists already or not
if (FAT32_SFNexists(file->parentcluster, (char*)file->shortfilename)==FALSE)
break;
tailNum++;
}
while (tailNum<9999);
if (tailNum==9999)
return NULL;
// Add file to disk
if (!FAT32_AddFileEntry(file->parentcluster, (char*)file->filename, (char*)file->shortfilename, file->startcluster, file->filelength))
return NULL;
// General
file->bytenum = 0;
file->currentBlock = 0xFFFFFFFF;
file->inUse = TRUE;
FAT32_PurgeFATBuffer();
return file;
}
#endif
//-----------------------------------------------------------------------------
// fl_fputc: Write a character to the stream
//-----------------------------------------------------------------------------
#ifdef INCLUDE_WRITE_SUPPORT
int fl_fputc(int c, FL_FILE *file)
{
BYTE Buffer[1];
// If first call to library, initialise
CHECK_FL_INIT();
if (file==NULL)
return -1;
// Check if file open
if (file->inUse==FALSE)
return -1;
// Append writes to end of file
if (file->Append)
file->bytenum = file->filelength;
// Else write to current position
// Write single byte
Buffer[0] = (BYTE)c;
if (_write_block(file, Buffer, 1))
return c;
else
return -1;
}
#endif
//-----------------------------------------------------------------------------
// fl_fwrite: Write a block of data to the stream
//-----------------------------------------------------------------------------
#ifdef INCLUDE_WRITE_SUPPORT
int fl_fwrite(const void * data, int size, int count, FL_FILE *file )
{
// If first call to library, initialise
CHECK_FL_INIT();
if (file==NULL)
return -1;
// Check if file open
if (file->inUse==FALSE)
return -1;
// Append writes to end of file
if (file->Append)
file->bytenum = file->filelength;
// Else write to current position
if (_write_block(file, (BYTE*)data, (size*count) ))
return count;
else
return -1;
}
#endif
//-----------------------------------------------------------------------------
// fl_fputs: Write a character string to the stream
//-----------------------------------------------------------------------------
#ifdef INCLUDE_WRITE_SUPPORT
int fl_fputs(const char * str, FL_FILE *file)
{
// If first call to library, initialise
CHECK_FL_INIT();
if (file==NULL)
return -1;
// Check if file open
if (file->inUse==FALSE)
return -1;
// Append writes to end of file
if (file->Append)
file->bytenum = file->filelength;
// Else write to current position
if (_write_block(file, (BYTE*)str, (UINT32)strlen(str)))
return (int)strlen(str);
else
return -1;
}
#endif
//-----------------------------------------------------------------------------
// _write_block: Write a block of data to a file
//-----------------------------------------------------------------------------
#ifdef INCLUDE_WRITE_SUPPORT
static BOOL _write_block(FL_FILE *file, BYTE *data, UINT32 length)
{
UINT32 sector;
UINT32 offset;
UINT32 i;
BOOL dirtySector = FALSE;
// If first call to library, initialise
CHECK_FL_INIT();
if (file==NULL)
return FALSE;
// Check if file open
if (file->inUse==FALSE)
return FALSE;
// No write permissions
if (file->Write==FALSE)
return FALSE;
for (i=0;i<length;i++)
{
// Calculations for file position
sector = file->bytenum / 512;
offset = file->bytenum - (sector*512);
// If file block not already loaded
if (file->currentBlock!=sector)
{
if (dirtySector)
{
// Copy from file buffer to FAT driver buffer
memcpy(FATFS_Internal.currentsector, file->filebuf, 512);
// Write back current sector before loading next
if (!FAT32_SectorWriter(file->startcluster, file->currentBlock))
return FALSE;
}
// Read the appropriate sector
// NOTE: This does not have succeed; if last sector of file
// reached, no valid data will be read in, but write will
// allocate some more space for new data.
FAT32_SectorReader(file->startcluster, sector);
// Copy to file's buffer
memcpy(file->filebuf, FATFS_Internal.currentsector, 512);
file->currentBlock=sector;
dirtySector = FALSE;
}
// Get the data block
file->filebuf[offset] = data[i];
dirtySector = TRUE;
// Increase next read/write position
file->bytenum++;
}
// If some write data still in buffer
if (dirtySector)
{
// Copy from file buffer to FAT driver buffer
memcpy(FATFS_Internal.currentsector, file->filebuf, 512);
// Write back current sector before loading next
if (!FAT32_SectorWriter(file->startcluster, file->currentBlock))
return FALSE;
}
// Increase file size
file->filelength+=length;
// Update filesize in directory
FAT32_UpdateFileLength(file->parentcluster, (char*)file->shortfilename, file->filelength);
return TRUE;
}
#endif
//-----------------------------------------------------------------------------
// fl_remove: Remove a file from the filesystem
//-----------------------------------------------------------------------------
#ifdef INCLUDE_WRITE_SUPPORT
int fl_remove( const char * filename )
{
FL_FILE* file;
FAT32_ShortEntry sfEntry;
// If first call to library, initialise
CHECK_FL_INIT();
file = _find_spare_file();
if (file==NULL)
return -1;
// Clear filename
memset(file->path, '\n', sizeof(file->path));
memset(file->filename, '\n', sizeof(file->filename));
// Split full path into filename and directory path
FileString_SplitPath((char*)filename, file->path, file->filename);
// If file is in the root dir
if (file->path[0]==0)
{
file->parentcluster = FAT32_GetRootCluster();
file->inRoot = TRUE;
}
else
{
file->inRoot = FALSE;
// Find parent directory start cluster
if (!_open_directory(file->path, &file->parentcluster))
return -1;
}
// Using dir cluster address search for filename
if (FAT32_GetFileEntry(file->parentcluster, file->filename,&sfEntry))
{
// Initialise file details
memcpy(file->shortfilename, sfEntry.Name, 11);
file->filelength = sfEntry.FileSize;
file->bytenum = 0;
file->startcluster = (((UINT32)sfEntry.FstClusHI)<<16) + sfEntry.FstClusLO;
file->currentBlock = 0xFFFFFFFF;
// Delete allocated space
if (!FAT32_FreeClusterChain(file->startcluster))
return -1;
// Remove directory entries
if (!FAT32_MarkFileDeleted(file->parentcluster, (char*)file->shortfilename))
return -1;
FAT32_PurgeFATBuffer();
return 0;
}
else
return -1;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -