⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat32_filelib.c

📁 FAT32代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	// 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 + -