这个问题与Python 2.7.1中的filecmp
module有关。据我所知,这两个调用是相同的(Windows,所以案例差异不应该是重要的)。一个返回True
而另一个返回False
。
>>> filecmp.cmp(r'h:\dcim\112_1029\imgp7258.dng', r'd:\pictures\2016\112_1029\imgp7258.dng', False)
True
>>> filecmp.cmp('h:\\dcim\\112_1029\\IMGP7258.DNG', 'd:\\pictures\\2016\\112_1029\\IMGP7258.DNG', False)
False
h:
是SD卡,而d:
是标准硬盘。我已经通过资源管理器将文件从h:
复制到d:
,因此 应该相同。为了确定,我甚至再次这样做了。每次调用的结果都是一致的,无论我做了多少次,或者我做了多少次。
这里还有一些实验,只是为了进一步混淆。
>>> f1 = r'h:\dcim\112_1029\imgp7258.dng'
>>> f2 = r'd:\pictures\2016\112_1029\imgp7258.dng'
>>> f3 = 'h:\\dcim\\112_1029\\IMGP7258.DNG'
>>> f4 = 'd:\\pictures\\2016\\112_1029\\IMGP7258.DNG'
>>> f1.upper()==f3.upper()
True
>>> f2.upper()==f4.upper()
True
>>> filecmp.cmp(f1, f2, False)
True
>>> filecmp.cmp(f3, f4, False)
False
>>> filecmp.cmp(f1, f4, False)
True
>>> filecmp.cmp(f3, f2, False)
True
根据评论中的要求,以下是4个文件名中每个文件名os.stat
的结果。除了访问和创建时间之外,您可以看到它们是相同的,但每个版本的文件名的时间都是一致的。
>>> os.stat(f1)
nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=15112724L, st_atime=1490418000L, st_mtime=1477766688L, st_ctime=1477766686L)
>>> os.stat(f2)
nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=15112724L, st_atime=1490488519L, st_mtime=1477766688L, st_ctime=1490488519L)
>>> os.stat(f3)
nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=15112724L, st_atime=1490418000L, st_mtime=1477766688L, st_ctime=1477766686L)
>>> os.stat(f4)
nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=15112724L, st_atime=1490488519L, st_mtime=1477766688L, st_ctime=1490488519L)
我想到的另一项测试:
>>> def hashfile(filename):
m = hashlib.md5()
with open(filename, 'rb') as f:
m.update(f.read())
return ''.join('%02x' % ord(b) for b in m.digest())
>>> hashfile(f1)
'a0042d8623567bcf429069d17e7c3148'
>>> hashfile(f2)
'a0042d8623567bcf429069d17e7c3148'
>>> hashfile(f3)
'a0042d8623567bcf429069d17e7c3148'
>>> hashfile(f4)
'a0042d8623567bcf429069d17e7c3148'
>>> filecmp.cmp(f1, f2, False)
True
>>> filecmp.cmp(f3, f4, False)
False
答案 0 :(得分:0)
documentation for 2.7没有提到它,但documentation for 3.4包含了这个非常重要的注释:
此函数使用缓存进行过去的比较和结果,如果文件的os.stat()信息发生更改,则缓存条目无效。可以使用clear_cache()清除整个缓存。
缓存在文件名上似乎区分大小写。
在我的情况下,我重新复制了文件,因此import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MultiLineOptionPane {
private JPanel pane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new MultiLineOptionPane()::createAndShowGui);
}
public void createAndShowGui() {
pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
StringBuilder sb = new StringBuilder(); //This object will be used to concatenate in the next for loop
for (int i = 0; i < 500; i++) { //Sample for loop
if ((i) % 10 == 0) { //Every 10 numbers we restart the StringBuilder
pane.add(new JLabel(sb.toString())); //We add a new JLabel to the JPanel with the contents of the StringBuilder
sb.delete(0, sb.length()); //We restart the StringBuilder
} else {
sb.append(i); //We append the current number to the StringBuilder
sb.append(" "); //We append a space after the number
}
}
pane.add(new JLabel(sb.toString())); //We add the last line of numbers in the StringBuilder to the pane
JOptionPane.showMessageDialog(new JFrame(), pane, "Numbers", JOptionPane.PLAIN_MESSAGE); //We display the message
}
}
信息没有改变(Windows保留了这些属性)。但是,当我在不同的情况下使用文件名进行测试时,我获得了与缓存结果不同的未缓存结果。
按照文档中的建议调用os.stat()
是解决我问题的确切方法。