标题: [文件操作] [讨论]dir /od 果真是按照时间排序的么? [打印本页]
作者: namejm 时间: 2011-5-17 18:44 标题: [讨论]dir /od 果真是按照时间排序的么?
本帖最后由 namejm 于 2011-5-18 19:18 编辑
在dir的帮助信息中,对参数 /OD 的解释是: 按日期/时间(从先到后)
果真如此?
我们来做个试验:- @echo off
- for /l %%i in (1,1,300) do cd.>%%i.txt
- dir /a-d /b /od *.txt
- pause
复制代码
结果截图:
[attach]3816[/attach]
谁能看出这些文件到底是按什么顺序排列的?
别问我
我也不知道
看了一下各位的回帖
貌似各个系统之间有所差别
补充一下我的测试环境:
WindowsXP_Pro_SP3,简体中文版
或许这是dir的一个bug
可能到了Win7下被修复了
一如N年前在XP_SP2下用 reg querry 查询含中文字符的字符串会被“吃掉”部分字符,到了XP_SP3下已经被修复了一样
作者: michael8111 时间: 2011-5-17 19:06
- for /l %%i in (1,1,300) do cd.>%%i.txt
复制代码
这个命令的运行只需要大约3秒钟,也就是说,平均每秒钟100个文件。
dir /od的时间判断可能没有这么精确(精确到0.01秒),所以就出现了如图情况(图上的文件名均小于100,而这些文件都是同一秒创建的)
作者: caruko 时间: 2011-5-17 19:10
楼上正解。
作者: CrLf 时间: 2011-5-17 19:18
本帖最后由 zm900612 于 2011-5-17 19:21 编辑
复杂,占位思考
虽说是同一秒内创建,但是它的排序总应该遵循什么规律吧,要不然两次dir的结果将是不同的
作者: CrLf 时间: 2011-5-17 19:28
而且,这个顺序似乎在创建时就注定了的- @echo off
- for /l %%i in (1,1,300) do cd.>%%i.txt
- dir /a-d /b /od *.txt>tmp1
- dir /a-d /b /od *.txt>tmp2
- fc tmp1 tmp2
- pause
复制代码
- @echo off
- for /l %%i in (1,1,300) do cd.>%%i.txt
- dir /a-d /b /od *.txt>tmp1
- for /l %%i in (1,1,300) do cd.>%%i.txt
- dir /a-d /b /od *.txt>tmp2
- fc tmp1 tmp2
- pause
复制代码
作者: michael8111 时间: 2011-5-17 19:29
本帖最后由 michael8111 于 2011-5-17 19:33 编辑
楼上:经过测试,两次dir的结果确实是不同的。我只截取一段以证明:
第一次:- 1.txt
- 2.txt
- 6.txt
- 5.txt
- 4.txt
- 7.txt
- 3.txt
- 8.txt
- 12.txt
- 13.txt
- 10.txt
- 9.txt
- 11.txt
- 15.txt
- 16.txt
复制代码
第二次:- 1.txt
- 3.txt
- 4.txt
- 5.txt
- 6.txt
- 2.txt
- 7.txt
- 11.txt
- 10.txt
- 12.txt
- 8.txt
- 9.txt
- 17.txt
- 14.txt
- 18.txt
复制代码
那么,每一次创建300个文件的代码都是一样的,而结果却不同。dir的排序究竟遵循什么规律?这个有待于发现。
作者: CrLf 时间: 2011-5-17 19:34
6# michael8111
两次dir中的txt是同一批的吗?我用5楼的代码试验,同批次的没有区别,不同批的则存在区别
作者: michael8111 时间: 2011-5-17 19:37
对,不同批的存在区别。
另外:- @echo off
- for /l %%i in (1,1,300) do (
- ping -n 1 127.1>nul
- cd.>%%i.txt
- )
- dir /a-d /b /od *.txt
- pause
复制代码
这次执行后,dir的顺序完全变成正常顺序。
再另外:
6楼的结果是win7下的测试结果,300个文件的排序只有微小的差别,而不是像楼主的截图一样有巨大的差别。难道dir的排序与操作系统有关?或者与电脑的快慢有关?
作者: michael8111 时间: 2011-5-17 19:40
9楼发的是什么?
作者: mxxcgzxxx 时间: 2011-5-17 19:40
本帖最后由 mxxcgzxxx 于 2011-5-17 19:45 编辑
你试下创建1000个文件的FOR,并每次显示一下%%1,会发现在数完前,并没有文件生成,所以应该是FOR创建文件的问题吧!- for /l %%1 in (1,1,1000) do echo %%1&cd.>%%1.txt
复制代码
原理应该和FOR中的GOTO是一样的道理。循环结束后才执行循环中的有效任务
作者: michael8111 时间: 2011-5-17 19:42
8楼的代码比较易于观察,观察后发现:
每一个ping的延时之后都生成一个文件,所以FOR /l是每循环一次就创建一个文件
作者: CrLf 时间: 2011-5-17 19:43
10# mxxcgzxxx
文件其实已经创建了,只是explorer刷新不够快而已,这很容易证明的,把文件数改成1000000,然后在没数完的时候刷新一下看看就知道了
作者: mxxcgzxxx 时间: 2011-5-17 19:47
本帖最后由 mxxcgzxxx 于 2011-5-17 19:54 编辑
10# mxxcgzxxx
文件其实已经创建了,只是explorer刷新不够快而已,这很容易证明的,把文件数改成1000000,然后在没数完的时候刷新一下看看就知道了
zm900612 发表于 2011-5-17 19:43
哦,那是我对CMD的理解还不到位
试了一下10000次的,确实是早已创建文件,但有趣的是我的显示好多秒才显完10000,而10000个文还是在同一秒里创建的,而我刷新时也是出现3000、8000、10000几个层次出现文件,这就有趣了!是什么原因?
作者: CrLf 时间: 2011-5-17 19:48
忽然发现fc Tmp1 Tmp2的时候,回显中的Tmp1是按照原文件名的大小写来显示,而Tmp2则被自动转为大写,看来这一特性很适合将长字符串的小写字母转大写呀
作者: mxxcgzxxx 时间: 2011-5-17 19:49
那就是说创建文件的速度太快,而系统最小只能识别到秒。必须给个延时让创建的时间有秒级上的区别才能正确排序!
这样理解对不!
作者: michael8111 时间: 2011-5-17 19:52
14# zm900612
可以用for把第二个文件名提取出来,就转换大小写了。
不过,dir既然无法精确判断时间,那么当dir判断这两个文件的创建时间“相同”时,dir是根据什么规律“固定”这300个文件的顺序?
作者: michael8111 时间: 2011-5-17 19:53
15# mxxcgzxxx
这样似乎也不对。。。
8楼的代码有ping -n 1 127.1>nul
但是这句代码的延时时间估计也只有半秒多,所以dir还不是以秒为单位,而是比秒更短的单位
作者: caruko 时间: 2011-5-17 19:55
16# michael8111
这点很难判断了..
或许根据磁盘的文件映射表也不一定。
作者: mxxcgzxxx 时间: 2011-5-17 20:06
是我弄错了,将分看成秒了。
第一个文件19:51.04
第一万个文件19:51.38
用资源管理器查看修改时间排序10000个文件无错。
但用dir /a-d /b /od *.txt 查看顺序就是有个别会乱
作者: michael8111 时间: 2011-5-17 20:09
看来 explorer.exe和dir的排序方式有所不同 或许explorer更为精确
dir有误差的问题还没解决 而namejm的测试结果差别更大 更是匪夷所思
作者: mxxcgzxxx 时间: 2011-5-17 20:13
我又试了一次更有趣了,我用cmd窗口下输入 DIR/od 结果和用批处理的又不一样了,更乱了
作者: michael8111 时间: 2011-5-17 20:18
21# mxxcgzxxx
你应该在命令提示符下输入:复制代码
这样的测试结果 和批处理完全相同
在cmd和批处理中的命令应该完全相同 才能比较结果
作者: CrLf 时间: 2011-5-17 20:34
本帖最后由 zm900612 于 2011-5-17 20:36 编辑
看来 explorer.exe和dir的排序方式有所不同 或许explorer更为精确
dir有误差的问题还没解决 而namejm的测试结果差别更大 更是匪夷所思
michael8111 发表于 2011-5-17 20:09
explorer对待时间一样的文件,似乎是名称为依据- @echo off
- for /l %%i in (10,-1,1) do cd.>@a%%i.txt
- for /l %%i in (1,1,10) do cd.>@b%%i.txt
- pause
复制代码
分别用升序和降序生成的文件,在explorer中的排列次序是相同的
作者: michael8111 时间: 2011-5-17 20:43
哦 那dir的规律是否也可以通过多次试验来推导出
作者: hanyeguxing 时间: 2011-5-17 20:56
dir /od 先按时间排列,时间完全相同的部分则按名称排列
作者: CrLf 时间: 2011-5-17 21:00
dir /od 先按时间排列,时间完全相同的部分则按名称排列
hanyeguxing 发表于 2011-5-17 20:56
可是这也解释不通楼主附图的前十行呀?
作者: michael8111 时间: 2011-5-17 21:10
25# hanyeguxing
原来的代码创建文件的顺序是从1.txt按顺序排到300.txt
然而1楼 6楼等的结果都是乱序的
如果是先按时间 后按名称 应该严格按照1到300排列 但事实却不是如此
作者: Hello123World 时间: 2011-5-18 15:56
我的是按照时间排序的(你系统问题吧)。
不过依照的是创建时间还是最后修改时间?- @echo off
- for /l %%i in (1,1,300) do cd.>%%i.txt
- dir /a-d /b /od *.txt >>hello.txt
- pause
复制代码
复制代码
作者: CrLf 时间: 2011-5-18 16:08
28# Hello123World
同样的代码在我机子上的运行结果仍非顺序,要不老兄试试逆序生成文本,再dir?
作者: Hello123World 时间: 2011-5-18 17:30
- @echo off
- for /l %%i in (300 -1 1) do cd.>%%i.txt
- dir /a-d /b /od *.txt >>hello.txt
- pause
复制代码
这样就是300到1,还是按顺序来的,我是win7企业版。
作者: CrLf 时间: 2011-5-18 17:40
30# Hello123World
看来系统之间的差别很大呀,在我机子上,虽然有部分乱序,但总体排序还是按照生成的时间先后排列,也就是说,顺序生成就基本上按顺序排列,逆序生成就基本是按逆序排列,我是盗版旗舰win7。
作者: michael8111 时间: 2011-5-18 19:53
我也是win7,与31楼的结果相同
不过28楼 和 30楼的执行结果有些匪夷所思 不知道为什么 namejm的贴图顺序更乱
现在问题越来越严重:dir究竟对于这种情况怎么排列(请注意,排列顺序在文件创建时就固定了)
作者: CrLf 时间: 2011-5-18 20:50
本帖最后由 zm900612 于 2011-5-18 21:02 编辑
我觉得最好申明一下磁盘格式,我当时的测试盘是ntfs的,不知道楼上几位是不是
反正我感觉要么和mft有关,要么和簇有关
作者: CrLf 时间: 2011-5-18 21:02
刚到别人机子上实验了下,貌似18楼当时说对了,应该确实和文件映射有关,ntfs格式的分区下出现少量乱序,fat32下则严格按照先后顺序排列,看来以后碰到这种问题要小心了。
作者: michael8111 时间: 2011-5-18 21:09
楼上 我用fat32的U盘测试 发现不但没有严格按照先后排列 反而更乱了 就像namejm的图那样
看来fat32的文件系统也要分情况……
作者: batman 时间: 2011-5-18 21:21
呵呵,我测试的结果很正常,本人环境sp3-fat32。。。
作者: michael8111 时间: 2011-5-18 21:31
我这个顺序是非常无厘头的……- ……
- (以上均正常)
- 80.txt
- 121.txt
- 120.txt
- 119.txt
- 118.txt
- 117.txt
- 116.txt
- 115.txt
- 114.txt
- 113.txt
- 112.txt
- 111.txt
- 110.txt
- ……
- (以下均倒序排列)
- ……
- 83.txt
- 82.txt
- 81.txt
- 135.txt
- 165.txt
- 166.txt
- 167.txt
- 168.txt
- 169.txt
- ……
- (以下均正序排列)
- ……
- 189.txt
- 190.txt
- 191.txt
- 163.txt
- 162.txt
- 161.txt
- 160.txt
- 159.txt
- ……
- (以下均倒序排列)
- ……
- 139.txt
- 138.txt
- 137.txt
- 122.txt
- 123.txt
- 124.txt
- ……
- (122-134正序)
- ……
- 164.txt
- 136.txt
- 257.txt
- 256.txt
- 255.txt
- ……
- (以下均倒序排列)
- ……
- 194.txt
- 193.txt
- 192.txt
- 230.txt
- 229.txt
- (230-203倒序)
- 300.txt
- 299.txt
- 298.txt
- 297.txt
- (300-258倒序)
- 292.txt
复制代码
作者: michael8111 时间: 2011-5-18 21:33
这个顺序是在fat32的U盘上的测试结果
顺序非常混乱 有点像1楼
36楼的结果正常 37楼就乱了
这到底是怎么回事……
难道dir的排序跟具体的每一个磁盘的设置(比如“簇”等)有关?
作者: michael8111 时间: 2011-5-18 21:35
一会正序 一会倒序 时不时又冒出来一个毫无规律的
毫无规律的可以理解(时间的判断不精确) 但是在一些部分中何来的极其标准的倒序(见37楼顺序) 这跟文件创建的顺序正好相反
作者: CrLf 时间: 2011-5-18 22:49
U盘另算,那个和硬盘不一样
作者: qzwqzw 时间: 2011-5-19 10:40
首先在cmd下
dir缺省是以文件名排序显示的
其次文件的修改时间只精确到秒级
当文件的修改时间相同时
以修改时间排序显示时
会按照文件的逻辑存储顺序显示
以下内容仅止于猜测
文件的逻辑存储顺序
与NTFS或者FAT32的文件系统格式无关
而是与磁盘的IO与缓存性能有关
也就是说当系统的磁盘IO与缓存性能极好
且当前无其他显著的磁盘IO任务
那么文件的逻辑存储顺序与文件创建顺序基本一致
如果系统磁盘IO与缓存性能很差
比如闪存盘的IO读写性能
或者当前有其他显著的磁盘IO任务
比如后台的病毒扫描任务
那么文件的逻辑存储顺序与文件创建顺序差异会很大
作者: michael8111 时间: 2011-5-19 19:23
但是如果“逻辑存储顺序”出现倒序 那就应该与IO无关了
我在磁盘没有显著IO任务,且IO性能“比较”好的情况下 做了100组实验数据 结果都是乱序
我贴出一部分 证明dir的顺序在“理想”的磁盘环境中也会是乱的:- 80.txt
- 82.txt
- 81.txt
- 83.txt
- 86.txt
- 87.txt
- 84.txt
- 88.txt
- 85.txt
- 94.txt
- 92.txt
- 93.txt
- 91.txt
- 89.txt
- 90.txt
- 96.txt
- 97.txt
- 98.txt
- 100.txt
- 95.txt
- 99.txt
复制代码
另外:
ping -n 1 127.1>nul
这条命令的执行时间只有大约半秒
然而如果每隔这个时间间隔创建一个文件 那么dir的顺序就是标准的
也就是说 dir的修改时间应该比秒精确一点
作者: mxxcgzxxx 时间: 2011-5-19 21:01
本帖最后由 mxxcgzxxx 于 2011-5-19 21:02 编辑
41# qzwqzw
我想了很久,比较倾向于41楼的说法
有可能是缓存造成的写入延时或别的什么顺序错误
作者: qzwqzw 时间: 2011-5-19 22:34
42# michael8111
“比较”以及“理想”都是一个模糊的词
需要一个量化的指标来进行标定
可能需要一个脚本
另外修改时间确实是秒级
这是文件存储的数据结构所决定的
dir不可能会检查到低于秒级的单位
这种情况只可能是因为有足够的时间缓冲
文件得以按顺序逐一flush到磁盘中
所以dir才能按照创建顺序展示
作者: Batcher 时间: 2011-5-19 23:09
44# qzwqzw
由于磁盘缓存的存在,我很好奇它到底是不是依次逐一写磁盘的。有没有详细的资料可供参考?
作者: CrLf 时间: 2011-5-19 23:11
45# Batcher
!!磁盘缓存...
作者: qzwqzw 时间: 2011-5-20 10:56
46# zm900612
已经试验证实文件逻辑存储顺序与文件系统有关
对一个磁盘分区先后格式化为NTFS、FAT32、exFAT三种FS格式
拷入以下脚本文件反复测试文件逻辑存储的偏移
结果发现在同一台PC上
NTFS总是具有明显的偏移
FAT32和exFAT则几乎没有
另外发现NTFS下文件写入的速度的明显快于FAT32/exFAT
推测正因为NTFS采取了更为高效的缓存机制
所以一方面导致文件读写性能大幅提升
另一方面导致文件的逻辑存储顺序随机化- @echo off & setlocal EnableDelayedExpansion
- for /l %%i in (1,1,300) do echo.A>%%i.xxx
- set maxoffset=0
- set minoffset=0
- for /f %%f in ('dir /a-d /b /od *.xxx') do (
- set/p=%%f <nul
- set /a count+=1
- set /a offset=%%~nf-count
- if !offset! gtr !maxoffset! set maxoffset=!offset!
- if !offset! lss !minoffset! set minoffset=!offset!
- )
- echo.
- echo ----------- %minoffset% : %maxoffset% -----------------
- pause
- del *.xxx
复制代码
作者: CrLf 时间: 2011-5-22 16:47
46# zm900612
已经试验证实文件逻辑存储顺序与文件系统有关
对一个磁盘分区先后格式化为NTFS、FAT32、exFAT三种FS格式
拷入以下脚本文件反复测试文件逻辑存储的偏移
结果发现在同一台PC上
NTFS总是具有明显的 ...
qzwqzw 发表于 2011-5-20 10:56
看来有结论了,嘿嘿
作者: michael8111 时间: 2011-5-22 18:33
48# zm900612
还有“推测”二字……
目前还无法证明:NTFS是否会导致文件的存储顺序随机化
作者: mxxcgzxxx 时间: 2011-5-23 06:51
要想有结论看来要去专业硬件论坛咨询了!
作者: plp626 时间: 2011-5-23 23:30
fastlz说,wmi 。。。。
一针见血。。。
作者: qzwqzw 时间: 2011-5-24 08:53
51# plp626
辞不达意
看不出跟上下文有什么关联
作者: fastslz 时间: 2011-5-24 11:04
用wmi获取的文件写入时间FAT32,exFAT可以精确到100毫秒以内,NTFS可以精确到100000毫秒以内,应该是这些信息决定了它的排列方式
我这里xp和Windows7排列方式一样的,所以不应该存在BUG
每台电脑排列方式不一样可以这样解释,比如用for创建300个文件奔3级CPU创建可能所需时间更长- @echo off
- :测试方法放在不同文件系统的根目录下
- set adir=%~d0
- ver|find "5.1"&&set v=5.1
- ver|find "6.1"&&set v=6.1
-
- if defined v (
- md %adir%\%v%-Test 2>nul
- if not exist %adir%\%v%-Test\*.txt for /l %%i in (1,1,300) do cd.>%adir%\%v%-Test\%%i.txt
- )
-
- for %%i in (5.1,6.1) do (
- if exist %adir%\%%i-Test\*.txt (
- Wmic Datafile Where "Extension='txt' and Drive='%adir%' and path='\\%%i-Test\\'" get CreationDate,name>%%i-Test-%v%-wmi.txt
- dir /a-d /b /od %adir%\%%i-Test\*.txt>%%i-Test-%v%-od.txt
- ))
复制代码
引用NTFS百度百科
对DOS略知一二的读者一定熟悉文件的各种属性:只读、隐藏、系统等。在NTFS文件系统中,这些属性都还存在,但有了很大不同。在这里,一切东西都是一种属性,就连文件内容也是一种属性。这些属性的列表不是固定的,可以随时增加,这也就是为什么你会在NTFS分区上看到文件有更多的属性.
NTFS文件系统中的文件属性可以分成两种:常驻属性和非常驻属性,常驻属性直接保存在MFT中,像文件名和相关时间信息(例如创建时间、修改时间等)永远属于常驻属性,非常驻属性则保存在MFT之外,但会使用一种复杂的索引方式来进行指示。如果文件或文件夹小于1500字节(其实我们的电脑中有相当多这样大小的文件或文件夹),那么它们的所有属性,包括内容都会常驻在MFT中,而MFT是Windows一启动就会载入到内存中的,这样当你查看这些文件或文件夹时,其实它们的内容早已在缓存中了,自然大大提高了文件和文件夹的访问速度。
NTFS 20110524103722.675442+480 1.txt
FAT32 20110524103651.520000+*** 1.txt
480包含了时区,表示相对于UTC的时差分钟数,中国是第八时区,相差480分钟
作者: fastslz 时间: 2011-5-24 11:36
NTFS 维基百科写的更全面一些
NTFS可以精确到100000毫秒以内(其实没那么精确)
+480取决于文件创建时系统当前设置的时区,而当前时区可以是动态的,如果这个文件拿到不同时区的电脑上,加减480值来获取相应当前系统时区的文件创建时间
作者: qzwqzw 时间: 2011-5-24 15:41
54# fastslz
NTFS可以精确到100000毫秒以内
可能是描述性错误
NTFS的创建时间可以精确到0.000001毫秒
wmic的结果说明不了太多的问题
只能说明ntfs的文件是成批的flush的
而且wmic的CreationDate还出现了错误
在删除文件后重新创建该文件
该文件的CreationDate显示的还是上一次创建时间
测试代码如下:- @echo off
- for /l %%i in (1,1,30) do echo.A>%%i.xxx
- Wmic Datafile Where "Extension='xxx' and Drive='d:' and Path='\\Test\\temp\\'" get CreationDate,name /format:htable:"sortby=CreationDate"> batfile.html
- del *.xxx
- for /l %%i in (1,1,30) do echo.A>%%i.xxx
- Wmic Datafile Where "Extension='xxx' and Drive='d:' and Path='\\Test\\temp\\'" get CreationDate,name /format:htable:"sortby=CreationDate">> batfile.html
- del *.xxx
- start batfile.html
复制代码
现在已经大致有了NTFS写入文件的轮廓
文件句柄的创建与关闭肯定是顺序的
文件首先写入到缓存(可能是内存或虚拟内存)中
缓存上的文件数据块受缓存管理器管理
无论NTFS、FAT32还是exFAT都是统一的缓存管理器
NTFS卷上的文件更新时需要先更新日志文件
以便于数据文件写入失败时可以继续或者撤销
在日志文件写入物理存储之前
数据文件被缓存管理器定义为不可写NO WRITE状态
而日志文件的写入时机是受缓存管理器约束的
为了提高IO性能
缓存管理器对数据文件和日志文件的管理是多线程并发的
而受到Windows核心对CPU资源的管理策略影响
并发线程的执行顺序有一定的随机性
所以数据文件的实际写入顺序存在一定的随机性
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |