我想使用它们自己的元数据重命名 mp3 文件并对它们进行排序(有/没有元数据),并在他执行语句时获得粗略的结果和奇怪的 FileNotFound 错误(图片如下)
粗略结果-> 两首歌曲中的一首被正确重命名,但另一首歌曲有自己的标题分割,而一部分是名称的一部分,另一部分有点像新的子目录!?
错误-> FileNotFoundError: [WinError 2]
Python代码,非常短
print("Start")
tracks = []
tracksMeta = []
tracksNoMeta = []
source = os.path.join(os.getcwd(), "testSongs") #os.getcwd()
dest = os.path.join(source, "ohneMeta")
destM = os.path.join(source, "mitMeta")
print(source)
print(dest)
print(destM)
print(os.path.exists(source))
print(os.path.exists(dest))
print(os.path.exists(destM))
if not os.path.exists(dest):
os.makedirs(dest)
if not os.path.exists(destM):
os.makedirs(destM)
for root, dirs, files, in os.walk(source):
for index, name in enumerate(files):
if name.endswith((".mp3",".m4a",".flac",".alac")):
tracks.append(name)
try:
temp_track = TinyTag.get(root + "\\" + name)
#metadata available
if temp_track.title and temp_track.artist:
print(index, name, "->", temp_track.artist, "-", temp_track.title)
tracksMeta.append(name + "->" + temp_track.title + "-" + temp_track.artist)
#rename
if os.access(source, os.W_OK):
print(temp_track.title)
print(temp_track.artist)
newname = temp_track.title + " - " + temp_track.artist + ".mp3"
if os.path.exists(source) and os.path.exists(destM):
os.renames(os.path.join(source, name), os.path.join(destM, newname))
#or not
else:
tracksNoMeta.append(name)
#move
if os.path.exists(source) and os.path.exists(dest):
os.renames(os.path.join(source, name), os.path.join(dest, name))
except TinyTagException:
print("Error")
你的代码的问题可能有几个原因,特别是 FileNotFoundError: [WinError 2]
和错误的文件路径。下面是一些可能的改进建议,以避免你的错误:
os.renames()
可能导致意外的目录创建os.renames()
不仅会重命名文件,还会尝试创建必要的目录。这可能会导致某些文件路径错误,比如 newname
变量可能包含非法字符(如 :
、/
等),导致文件变成目录。解决方案:使用 os.rename()
而不是 os.renames()
。
路径拼接问题
代码中的 root + "\\" + name
可能导致 FileNotFoundError
,建议使用 os.path.join(root, name)
以确保正确拼接路径。
文件名可能包含非法字符
Windows 不允许某些字符,如 :
、?
、*
,在文件名中。你需要在 newname
之前进行合法性检查。
os.access(source, os.W_OK)
可能不适用于 Windows
os.access(source, os.W_OK)
返回 True
,仍然可能无法重命名文件,因为文件可能被其他进程占用。import os
import re
from tinytag import TinyTag, TinyTagException
print("Start")
tracks = []
tracksMeta = []
tracksNoMeta = []
source = os.path.join(os.getcwd(), "testSongs")
dest = os.path.join(source, "ohneMeta")
destM = os.path.join(source, "mitMeta")
print(source)
print(dest)
print(destM)
print("Source exists:", os.path.exists(source))
print("Destination (no metadata) exists:", os.path.exists(dest))
print("Destination (with metadata) exists:", os.path.exists(destM))
# 确保目标目录存在
os.makedirs(dest, exist_ok=True)
os.makedirs(destM, exist_ok=True)
# 处理音频文件
for root, dirs, files in os.walk(source):
for index, name in enumerate(files):
if name.endswith((".mp3", ".m4a", ".flac", ".alac")):
tracks.append(name)
try:
file_path = os.path.join(root, name)
temp_track = TinyTag.get(file_path)
# 处理元数据
if temp_track.title and temp_track.artist:
print(index, name, "->", temp_track.artist, "-", temp_track.title)
tracksMeta.append(name + " -> " + temp_track.title + " - " + temp_track.artist)
# 规范化文件名(去除非法字符)
safe_title = re.sub(r'[<>:"/\\|?*]', '', temp_track.title)
safe_artist = re.sub(r'[<>:"/\\|?*]', '', temp_track.artist)
newname = f"{safe_title} - {safe_artist}.mp3"
new_path = os.path.join(destM, newname)
# 确保文件不存在后再重命名
if os.path.exists(file_path):
os.rename(file_path, new_path)
print(f"Moved: {file_path} -> {new_path}")
else:
tracksNoMeta.append(name)
# 移动无元数据的文件
new_path = os.path.join(dest, name)
if os.path.exists(file_path):
os.rename(file_path, new_path)
print(f"Moved (no metadata): {file_path} -> {new_path}")
except TinyTagException:
print(f"Error reading metadata for: {name}")
print("Done.")
✅ 使用 os.rename()
代替 os.renames()
✅ 使用 os.path.join()
代替字符串拼接
✅ 处理 Windows 不允许的文件名字符
✅ 使用 os.makedirs(dest, exist_ok=True)
避免重复创建目录
✅ 添加 print()
语句调试文件移动过程
这样可以避免你的 FileNotFoundError
,同时防止错误的子目录被创建。 🚀