我格式化我的闪存并选择其文件系统格式为FAT32:
然后看一下闪存驱动器的属性:
如上所示,已使用空间为 16KB。
我更改 Windows 选项以显示所有隐藏文件和系统文件:
看看闪存的内容。如你所见,它是空的:
为了确保万无一失,我还使用命令行列出了其内容:
I:\>dir /A
Volume in drive I is TRANSCEND
Volume Serial Number is 7E4F-5898
Directory of I:\
File Not Found
I:\>
正如您上面看到的,它是空的!
供你参考 :
/A
在命令行中,指示显示所有文件(隐藏文件,系统文件,...)
I:\>dir /?
Displays a list of files and subdirectories in a directory.
DIR [drive:][path][filename] [/A[[:]attributes]] [/B] [/C] [/D] [/L] [/N]
[/O[[:]sortorder]] [/P] [/Q] [/R] [/S] [/T[[:]timefield]] [/W] [/X] [/4]
[drive:][path][filename]
Specifies drive, directory, and/or files to list.
/A Displays files with specified attributes.
attributes D Directories R Read-only files
H Hidden files A Files ready for archiving
S System files I Not content indexed files
L Reparse Points - Prefix meaning not
/B Uses bare format (no heading information or summary).
/C Display the thousand separator in file sizes. This is the
default. Use /-C to disable display of separator.
/D Same as wide but files are list sorted by column.
/L Uses lowercase.
/N New long list format where filenames are on the far right.
/O List by files in sorted order.
sortorder N By name (alphabetic) S By size (smallest first)
E By extension (alphabetic) D By date/time (oldest first)
G Group directories first - Prefix to reverse order
/P Pauses after each screenful of information.
/Q Display the owner of the file.
/R Display alternate data streams of the file.
/S Displays files in specified directory and all subdirectories.
/T Controls which time field displayed or used for sorting
timefield C Creation
A Last Access
W Last Written
/W Uses wide list format.
/X This displays the short names generated for non-8dot3 file
names. The format is that of /N with the short name inserted
before the long name. If no short name is present, blanks are
displayed in its place.
/4 Displays four-digit years
Switches may be preset in the DIRCMD environment variable. Override
preset switches by prefixing any switch with - (hyphen)--for example, /-W.
当我使用以下方法格式化闪存时,这个问题变得更加有趣NTFS其文件系统格式如下:
正如你在下面看到的,在这种情况下,我输了125MB我的闪存空间:
我为FAT32,输出相同的结果NTFS
Q1:有什么问题?这个被占用的空间的来源在哪里?
问题 2:我可以看到那些占用该空间的文件吗?
为了获得更多乐趣,我安装了此闪存(格式化为NTFS) 在 Linux 中查看它:
太奇怪了!我们87.2MB
利用了空间!(在 Windows7 中则为 125MB)。
让我们通过命令查看其内容ls -a
:
哦!又没事了!
Q3:为什么同一个Flash在两个OS下的已用空间不一样?
更新:对于FAT32
格式,在 Windows 和 Linux [在本例中为 BackTrack] 中没有区别,并且在两者中我们都有16KB
。
感谢您的时间和考虑。
答案1
关于FAT32
TL;DR;
文件大小是通过计算文件分配表,胖的由于需要根目录条目,所以不能为空,因此 FAT 文件系统始终需要一个簇空间 (= Allocation unit size
)!
详细解答
FAT32 文件系统以群集为单位工作,这是Allocation size unit
您选择的。FAT32 的设计需要每个文件一个簇+一个簇用于根目录。
FAT32文件系统包含以下部分:
[从Paul 的 8051 代码库:了解 FAT32 文件系统]
簇区域被划分为大小相同的簇,例如 4k、8k、16k 和 32k。每个文件(包括根目录)占用一个或多个簇:
这卷 ID指定集群,其中根目录STARTS,通常是第三个簇,从 0 开始计数时是第二个簇。(
0x02C
)这根目录群集包含目录条目,这些是 32 字节结构,提供有关文件和目录的信息,最重要的是
- 姓名
- 文件类型(文件或目录)
- 1. 文件/目录的簇
- 文件/目录的大小。
要知道我们需要读取多少个文件和目录的簇,包括我们需要读取的根目录,
FAT #1
或者FAT #2
哪些是文件分配表s:- 为了实现冗余,两个 FAT 都包含相同的数据。
- FAT 为每个数据簇包含一个条目。
- 每个条目长度为 32 位(因此为 FAT32),
- 32 位 FAT 条目指定
- 文件或目录的下一个簇的编号,
- 这是文件/目录的最后一个簇(0xFFFFFFFF),
- 该集群为空(0x0)。
|3: 0x5 |4: 0x6 |5: 0xFFFFFFF |6: 0xFFFFFFF |7: 0x |8: 0x0 | ...
| 1. file start, next cluster 0x4 | 2. file start, next cluster 0x7 | 1. file ends here | 2. files ends here | Empty cluster | Empty | ...
因此,为了读取文件或目录,我们
- 从目录条目中读取起始扇区和文件大小。
- 从 FAT 中找出后续扇区。
- 按正确顺序读取扇区尺寸字节。
对于空的 FAT 文件系统FAT 在根目录的第 2 扇区包含一个条目,指定该扇区是最后一个扇区:
# for i in `seq 0 3`; do (fatcat -@ $i /dev/sda1 | grep FAT1); done
# fatcat => FAT filesystem explore, extract, repair, and forensic tool
# -@ <cluster> => display cluster info: offset, address, FAT entry
FAT1: 4294967295 (ffffffff) # sec 0
FAT1: 4294967295 (ffffffff) # sec 1
FAT1: 4294967295 (ffffffff) # sec 2, 1. and last sector for the root directory.
FAT1: 0 (00000000) # sec 3, empty because there are no more files/directories.
对于 Linux 系统,诸如此类的命令df
使用stat
系统调用,通过读取所有非FAT 条目statfs
来计算 FAT32 文件系统的已用空间:0x0
int fat_count_free_clusters(struct super_block *sb)
{
...
free = 0;
fatent_init(&fatent);
fatent_set_entry(&fatent, FAT_START_ENT);
fat_ra_init(sb, &fatent_ra, &fatent, sbi->max_cluster);
while (fatent.entry < sbi->max_cluster) {
/* readahead of fat blocks */
fat_ent_reada(sb, &fatent_ra, &fatent);
err = fat_ent_read_block(sb, &fatent);
if (err)
goto out;
do {
// WHEN FAT entry == 0x0 this entry is free space!
if (ops->ent_get(&fatent) == FAT_ENT_FREE)
free++;
} while (fat_ent_next(sbi, &fatent));
cond_resched();
}
sbi->free_clusters = free;
...
}
fs/fat/fatent.c#L714
Linux 内核 v5.13
因为您的Allocation unit size
(= 簇大小)是 16kB,所以 16kB 已经用于一个根目录 FAT 条目(3. 条目,0xFFFFFFFF)。