谁作过FAT File system? Fseek()这个函数看着有点迷糊,请高手指点一下大慨思路。源码如下: bit fat_fseek (Int32 offset) { Uint32 file_pos; /* current position in file */ Uint16 cluster_offset; /* cluster offset in file */ Byte sector_offset; /* sector offset in cluster */ #define i sector_offset /* local variable overlay */ #define byte_offset cluster_offset /* local variable overlay */
/* File size information update for write mode*/ if (fat_open_mode == WRITE) { if (fat_cache.current.size.l <= fat_file_size.l) fat_cache.current.size.l = fat_file_size.l; } /* init file pos with the current cluster in the index */ if (fat_fchain_nb_clust != 0) file_pos = fat_fchain_nb_clust - 1; else file_pos = 0; /* Add the previous cluster number */ for (i = 0; i != fat_fchain_index; i++) { file_pos += fclusters.number; } /* convert absolute cluster value in byte position */ file_pos *= SECTOR_SIZE * fat_cluster_size;
if ((fat_fchain_nb_clust != 0) && ( fat_fclust_byte_count % (fat_cluster_size * SECTOR_SIZE) == 0)) { file_pos += (fat_cluster_size * SECTOR_SIZE); } else { ((Byte*)&fat_fclust_byte_count)[0] &= fat_cluster_mask; file_pos += fat_fclust_byte_count; /* offset in cluster */ }
/* Check range value */ if (((file_pos + offset) < 0) || ((file_pos + offset) > fat_cache.current.size.l)) { return KO; /* out of file limits */ }
file_pos += offset; /* new position */
/* Calculate byte position in cluster */ ((Byte*)&fat_fclust_byte_count)[1] = ((Byte*)&file_pos)[3]; ((Byte*)&fat_fclust_byte_count)[0] = ((Byte*)&file_pos)[2];
/* Calculate the absolute cluster position */ cluster_offset = file_pos / (SECTOR_SIZE * fat_cluster_size); fat_fchain_index = 0; /* reset fragment number */
/* Determinate the index for the chain cluster */ while (cluster_offset >= fclusters[fat_fchain_index].number) { cluster_offset -= fclusters[fat_fchain_index].number; fat_fchain_index++; /* ome more fragment */ }
/* Determinate the cluster offset value for the selected index */ fat_fchain_nb_clust = cluster_offset;
/* Determinate the sector offset value in the selected cluster */ sector_offset = (fat_fclust_byte_count & ((fat_cluster_size * SECTOR_SIZE) - 1)) / SECTOR_SIZE;
/* seek into sector */ byte_offset = file_pos % SECTOR_SIZE;
/* re-open file in read or write mode */ if (fat_open_mode == READ) { Hard_read_close(); /* close reading */ Hard_read_open(((Uint32)(fclusters[fat_fchain_index].cluster + fat_fchain_nb_clust) * fat_cluster_size) + sector_offset + fat_ptr_data); if ((fat_fchain_nb_clust != 0) || (sector_offset != 0) || (byte_offset != 0)) { /* if no offset, nb_clust incremented in fgetc() function */ fat_fchain_nb_clust++; /* one-based variable */ } while (byte_offset != 0) { Hard_read_byte(); /* dummy read */ byte_offset--; } } else { Hard_write_close(); /* close writing */ Hard_write_open(((Uint32)(fclusters[fat_fchain_index].cluster + fat_fchain_nb_clust) * fat_cluster_size) + sector_offset + fat_ptr_data); byte_offset = file_pos % SECTOR_SIZE; if (byte_offset != 0) { /* if no offset, nb_clust incremented in fputc() function */ fat_fchain_nb_clust++; /* one-based variable */ } fat_file_size.l += offset; /* Update byte position in write mode */
if ((((Byte*)&fat_fclust_byte_count)[1] == 0x00) && ((((Byte*)&fat_fclust_byte_count)[0] & fat_cluster_mask) == 0x00)) { if ((fclusters[fat_fchain_index].number == fat_fchain_nb_clust) && (fat_fchain_index == fat_last_clust_index)) { flag_end_disk_file = TRUE; } else { flag_end_disk_file = FALSE; } } } return OK; } |