尝试重命名文件时指定了无效路径
An invalid path was specified when tried to rename file
我正在 Python 中编写一个版本升级脚本(一个自动版本号递增脚本),但我感觉重命名时发生了一件奇怪的事情Maya 中的代码。
我不确定 Maya 如何存储文件路径,但每当我尝试重命名它时,它都会告诉我 "An invalid path was specified." 以及我的文件路径。
而且我想更奇怪的是,它只在几个案例中提到了这个错误。一旦我尝试重命名 Maya 资产文件夹中的文件(是的,我已经为 Maya 设置了要查找的项目),它给了我那个错误。但是当我从 Maya 的场景文件夹中打开文件时一切正常。然后,在另一个项目文件夹中,无论我打开资产文件还是场景文件,一切都完美无缺。
有人知道发生了什么事吗?非常感谢!!!
a = cmds.file (query = True, expandName = True) #result: D:/DATA/MAYA/myProject/assets/testFolder/test_01.ma
#print a[:-3]
x,y = a[-5:-3] #result: x = 0, y = 1
x = int(x)
y = int(y)
if y < 9:
y += 1 #result: x = 0, y = 2
#print (y)
elif y == 9:
y = 0
x += 1
x = str(x)
y = str(y)
b = a.replace(a[-5:-3], x+y) #replace 01 with 02
#print b
cmds.file (rename = b) #this is where I got the error. the result should be D:/DATA/MAYA/myProject/assets/testFolder/test_02.ma
下面的方法非常冗长,因为我使用的是字符串操作而不是正则表达式。这有希望使它对您来说更具可读性,但我建议您在感觉足够舒适时移至正则表达式。
请注意,处理字符串格式以重命名场景的函数将使用最少 2 位数字(01、02 等)和最多 3 位数字(100、101 等)。如果超过 999 次迭代,则需要稍微修改一下。
注:
此方法依赖于文件版本前的下划线(例如 _01.mb),而不是当前的字符串索引方法。
import maya.cmds as cmds
def getNextVersion():
curName = cmds.file(query=True, expandName=True) # eg. D:/yourScene_01.mb
curVersionFull = curName.split('_')[-1] # eg. 01.mb
versionExtension = curVersionFull.split('.') # eg. ['01', 'mb']
curVersionNum = int(versionExtension[0]) # eg. 1
extension = versionExtension[1] # eg. 'mb'
nextVersionNum = curVersionNum + 1 # increment your version
if nextVersionNum < 100:
nextVersionFull = '{:02d}.{}'.format(nextVersionNum, extension) # eg. 02.mb
else:
nextVersionFull = '{:03d}.{}'.format(nextVersionNum, extension) # eg. 100.mb
newName = curName.replace(curVersionFull, nextVersionFull)
return newName
cmds.file(rename=getNextVersion())
cmds.file(save=True)
更新:
您已经接受了另一个答案,我相信您问题的核心是@green-cell 所描述的内容。至于这怎么可能,其实我也不知道。 Maya 通常不会让您保存到不存在的文件夹。
例如:
import maya.cmds as cmds
cmds.file(rename="D:/doesntexist/somefile.mb")
# Error: An invalid path was specified. : D:/doesntexist/
# Traceback (most recent call last):
# File "<maya console>", line 2, in <module>
# RuntimeError: An invalid path was specified. : D:/doesntexist/ #
无论如何,我在这里为您整理了一个更全面的功能。请注意,很难满足所有可能的文件名模式,特别是如果允许用户在过程的任何部分指定自己的文件名。这次我使用 regular expressions
,这使您的替代品更加可靠(尽管远非万无一失)。
import re
import os
import maya.cmds as cmds
def getNextVersion(createDir=True):
'''Find next available filename iteration based on current scene name
Args:
createDir (bool, optional): True to create the output directory if required. False to leave as-is (may trigger a failure)
Returns:
str|None: Full file path with incremented version number. None on failure
'''
# Grab current filename. This always returns something. If unsaved, it will return something unsavory, but still a string
curFile = cmds.file(query=True, expandName=True)
print('Current filename is {}'.format(curFile))
# This matches a digit between 1 and 4 numbers in length, followed immediately by a file extension between 2 and 3 characters long
m = re.match(r'(.+?)(\d{1,4})\.(\w{2,3})', curFile)
if m == None:
print('Failed at regex execution. Filename does not match our desired pattern')
return None
# Extract regex matches
basePath = m.group(1)
version = m.group(2)
extension = m.group(3)
# Failsafe. Should not trigger
if not basePath or not version or not extension:
print('Failed at failsafe. Filename does not match our desired pattern')
return None
# Increment file version
numDigits = len(version)
newFile = None
try:
version = int(version) + 1
# Deal with padding
newLength = len(str(version))
if newLength > numDigits:
numDigits = newLength
# Compile new path
newFile = '{base}{ver:{numDig:02d}d}.{ext}'.format(base=basePath, ver=version, numDig=numDigits, ext=extension)
except Exception as e:
print('Error parsing new version for path {}: {}'.format(curFile, e))
return None
# Another failsafe
if not newFile:
print('Failed at failsafe. Filename calculations succeeded, but new path is not valid')
return None
# Create output dir if needed
dirname = os.path.dirname(newFile)
if createDir and not os.path.isdir(dirname):
try:
os.makedirs(dirname)
print('Created all dirs required to build path {}'.format(dirname))
except Exception as e:
print('Error creating path {}: {}'.format(dirname, e))
return None
return newFile
nextVersion = getNextVersion()
if not nextVersion:
cmds.error('Error parsing new filename increment. Please see console for more information')
else:
cmds.file(rename=nextVersion)
cmds.file(save=True)
更新#02:
我意识到错误只发生在第一个版本上。假设我的第一个版本是 sceneName_01.ma 并尝试升级并保存它,Maya 会告诉我 "An invalid path was specified"。但是如果我手动将其重命名为sceneName_02.ma并再次重新运行代码,代码将正常运行。
虽然不是因为版本号。一旦我尝试将我的第一个版本保存为 sceneName_00.ma 并尝试脚本,它仍然给了我同样的错误。我不得不手动将其重命名为 sceneName_01.ma 并重新 运行 脚本,直到那时它才起作用。
# Error: RuntimeError: file <maya console> line 1: An invalid path was specified.
此错误在 运行 cmds.file(rename=your_path)
但提供的路径目录不存在时触发,这是有道理的,因为它 不是 有效!
所以您所要做的就是在调用它之前创建文件夹。您可以为此使用 os.makedirs
。您不想在完整路径中包含文件名,因此您也可以使用 os.path.dirname
将其删除。因此,使用 os.path.dirname
不是传递它 "/my/full/path/file_name.mb"
,而是将其剥离为 "/my/full/path"
.
因此扩展 itypewithmyhands 的答案将如下所示:
import os
newVersion = getNextVersion()
versionFolder = os.path.dirname(newVersion)
if not os.path.exists(versionFolder):
os.makedirs(versionFolder)
我正在 Python 中编写一个版本升级脚本(一个自动版本号递增脚本),但我感觉重命名时发生了一件奇怪的事情Maya 中的代码。
我不确定 Maya 如何存储文件路径,但每当我尝试重命名它时,它都会告诉我 "An invalid path was specified." 以及我的文件路径。
而且我想更奇怪的是,它只在几个案例中提到了这个错误。一旦我尝试重命名 Maya 资产文件夹中的文件(是的,我已经为 Maya 设置了要查找的项目),它给了我那个错误。但是当我从 Maya 的场景文件夹中打开文件时一切正常。然后,在另一个项目文件夹中,无论我打开资产文件还是场景文件,一切都完美无缺。
有人知道发生了什么事吗?非常感谢!!!
a = cmds.file (query = True, expandName = True) #result: D:/DATA/MAYA/myProject/assets/testFolder/test_01.ma
#print a[:-3]
x,y = a[-5:-3] #result: x = 0, y = 1
x = int(x)
y = int(y)
if y < 9:
y += 1 #result: x = 0, y = 2
#print (y)
elif y == 9:
y = 0
x += 1
x = str(x)
y = str(y)
b = a.replace(a[-5:-3], x+y) #replace 01 with 02
#print b
cmds.file (rename = b) #this is where I got the error. the result should be D:/DATA/MAYA/myProject/assets/testFolder/test_02.ma
下面的方法非常冗长,因为我使用的是字符串操作而不是正则表达式。这有希望使它对您来说更具可读性,但我建议您在感觉足够舒适时移至正则表达式。
请注意,处理字符串格式以重命名场景的函数将使用最少 2 位数字(01、02 等)和最多 3 位数字(100、101 等)。如果超过 999 次迭代,则需要稍微修改一下。
注: 此方法依赖于文件版本前的下划线(例如 _01.mb),而不是当前的字符串索引方法。
import maya.cmds as cmds
def getNextVersion():
curName = cmds.file(query=True, expandName=True) # eg. D:/yourScene_01.mb
curVersionFull = curName.split('_')[-1] # eg. 01.mb
versionExtension = curVersionFull.split('.') # eg. ['01', 'mb']
curVersionNum = int(versionExtension[0]) # eg. 1
extension = versionExtension[1] # eg. 'mb'
nextVersionNum = curVersionNum + 1 # increment your version
if nextVersionNum < 100:
nextVersionFull = '{:02d}.{}'.format(nextVersionNum, extension) # eg. 02.mb
else:
nextVersionFull = '{:03d}.{}'.format(nextVersionNum, extension) # eg. 100.mb
newName = curName.replace(curVersionFull, nextVersionFull)
return newName
cmds.file(rename=getNextVersion())
cmds.file(save=True)
更新:
您已经接受了另一个答案,我相信您问题的核心是@green-cell 所描述的内容。至于这怎么可能,其实我也不知道。 Maya 通常不会让您保存到不存在的文件夹。
例如:
import maya.cmds as cmds
cmds.file(rename="D:/doesntexist/somefile.mb")
# Error: An invalid path was specified. : D:/doesntexist/
# Traceback (most recent call last):
# File "<maya console>", line 2, in <module>
# RuntimeError: An invalid path was specified. : D:/doesntexist/ #
无论如何,我在这里为您整理了一个更全面的功能。请注意,很难满足所有可能的文件名模式,特别是如果允许用户在过程的任何部分指定自己的文件名。这次我使用 regular expressions
,这使您的替代品更加可靠(尽管远非万无一失)。
import re
import os
import maya.cmds as cmds
def getNextVersion(createDir=True):
'''Find next available filename iteration based on current scene name
Args:
createDir (bool, optional): True to create the output directory if required. False to leave as-is (may trigger a failure)
Returns:
str|None: Full file path with incremented version number. None on failure
'''
# Grab current filename. This always returns something. If unsaved, it will return something unsavory, but still a string
curFile = cmds.file(query=True, expandName=True)
print('Current filename is {}'.format(curFile))
# This matches a digit between 1 and 4 numbers in length, followed immediately by a file extension between 2 and 3 characters long
m = re.match(r'(.+?)(\d{1,4})\.(\w{2,3})', curFile)
if m == None:
print('Failed at regex execution. Filename does not match our desired pattern')
return None
# Extract regex matches
basePath = m.group(1)
version = m.group(2)
extension = m.group(3)
# Failsafe. Should not trigger
if not basePath or not version or not extension:
print('Failed at failsafe. Filename does not match our desired pattern')
return None
# Increment file version
numDigits = len(version)
newFile = None
try:
version = int(version) + 1
# Deal with padding
newLength = len(str(version))
if newLength > numDigits:
numDigits = newLength
# Compile new path
newFile = '{base}{ver:{numDig:02d}d}.{ext}'.format(base=basePath, ver=version, numDig=numDigits, ext=extension)
except Exception as e:
print('Error parsing new version for path {}: {}'.format(curFile, e))
return None
# Another failsafe
if not newFile:
print('Failed at failsafe. Filename calculations succeeded, but new path is not valid')
return None
# Create output dir if needed
dirname = os.path.dirname(newFile)
if createDir and not os.path.isdir(dirname):
try:
os.makedirs(dirname)
print('Created all dirs required to build path {}'.format(dirname))
except Exception as e:
print('Error creating path {}: {}'.format(dirname, e))
return None
return newFile
nextVersion = getNextVersion()
if not nextVersion:
cmds.error('Error parsing new filename increment. Please see console for more information')
else:
cmds.file(rename=nextVersion)
cmds.file(save=True)
更新#02:
我意识到错误只发生在第一个版本上。假设我的第一个版本是 sceneName_01.ma 并尝试升级并保存它,Maya 会告诉我 "An invalid path was specified"。但是如果我手动将其重命名为sceneName_02.ma并再次重新运行代码,代码将正常运行。
虽然不是因为版本号。一旦我尝试将我的第一个版本保存为 sceneName_00.ma 并尝试脚本,它仍然给了我同样的错误。我不得不手动将其重命名为 sceneName_01.ma 并重新 运行 脚本,直到那时它才起作用。
# Error: RuntimeError: file <maya console> line 1: An invalid path was specified.
此错误在 运行 cmds.file(rename=your_path)
但提供的路径目录不存在时触发,这是有道理的,因为它 不是 有效!
所以您所要做的就是在调用它之前创建文件夹。您可以为此使用 os.makedirs
。您不想在完整路径中包含文件名,因此您也可以使用 os.path.dirname
将其删除。因此,使用 os.path.dirname
不是传递它 "/my/full/path/file_name.mb"
,而是将其剥离为 "/my/full/path"
.
因此扩展 itypewithmyhands 的答案将如下所示:
import os
newVersion = getNextVersion()
versionFolder = os.path.dirname(newVersion)
if not os.path.exists(versionFolder):
os.makedirs(versionFolder)