我需要用EXIF数据重命名我的图片,但我有一个问题:如果我使用“:”分隔时间(小时:分钟:秒),文件名会变得疯狂!
metadata = pyexiv2.ImageMetadata(lunga + i)
metadata.read()
tag = metadata['Exif.Image.DateTime']
estensione = ".jpg"
new_data = tag.value.strftime('%Y-%m-%d %H-%M-%S')
new_name = lunga + str(new_data) + estensione
os.renames(lunga + i, new_name)
效果很好,但是
new_data = tag.value.strftime('%Y-%m-%d %H:%M:%S')
我得到像
这样的东西2A443K~H.jpg
答案 0 :(得分:2)
问题是你不允许在Windows上将冒号放入文件名。您实际上并没有使用Windows ...但 使用SMB共享,这意味着您受到Windows规则的约束。
修复方法是不将冒号放入文件名中。
如果你想了解为什么会发生这种奇怪的事情,请继续阅读。
有关Windows文件名的详细信息,请参阅MSDN上的Naming Files, Paths, and Namespaces,但我将在此汇总相关部分。
Windows下的NT内核没有冒号问题,但是它上面的Win32层无法处理它们(MSVCRT中的准POSIX层位于Win32之上)。
因此,在C级别,如果你调用像NtSetInformationFile
这样的NT函数,它会保存它们就好了。如果你调用像MoveFileEx
这样的Win32函数,它们通常会给你一个错误,但是如果你使用特殊的\\?\
语法来说“将这个名字直接传递给NT”,它就会起作用。如果您调用rename
之类的MSVCRT函数,则会出现错误。较早版本的Python称为rename
,它只会给你一个错误。较新版本调用MoveFileEx
,并尝试用\\?\
语法包装名称(因为这也允许您绕过其他一些愚蠢的限制,例如过短的MAX_PATH
值)。
那么,如果你给文件一个Win32无法理解的名字,会发生什么?请记住,在Windows上,每个文件都有两个不同的名称:“长名称”和“短名称”。短名称是DOS样式的8.3文件名。因此,只要它不能显示长名称,它就会显示短名称。
短名称来自哪里?如果您没有显式创建一个,Windows将使用前6个字符,波形符和数字来从长名称为您创建一个。因此,例如,"Program Files"
的简称是"PROGRA~1"
。但是如果Windows无法处理长名称,它将只用6个随机字符,波浪号和随机字符组成一个短名称。所以你会得到类似2A443K~H
的东西。
专为Windows设计的NTFS文件系统希望以Windows-y方式使用。因此,如果您正在使用NTFS卷,即使在非Windows系统上,驱动程序也会模拟其中一些功能,从而为您提供类似但不相同的行为。
当然,如果您正在与Windows系统中的共享或非Windows系统上的NTFS驱动器支持的共享进行通信,那么同样适用一些相同的事情。
即使您的计算机和文件服务器都是非Windows且文件系统不是NTFS,如果您使用SMB / CIFS进行文件共享,SMB也是为Windows设计的,您将再次获得类似的行为。
至少你不再需要担心VMS,经典Mac和其他命名系统,只需要POSIX和Windows。
答案 1 :(得分:1)
冒号是Windows文件系统中的保留字符(请参阅How would I go about creating a filename with invalid characters such as :?>?),因此该名称已替换为自动生成的。
要清楚,这是不是 Python问题。如果您不希望这种情况发生,请不要在文件名中使用冒号或其他保留字符。