Найти - Пользователи
Полная версия: Ошибка длинного имени в Windows
Начало » Python для новичков » Ошибка длинного имени в Windows
1 2 3
Alex2ndr
Всем доброго времени суток!

Получил я задачу написать скриптик резервного копирования. Обычно я все делаю под linux - но в этот раз мне не повезло - задача стоит написать под Mustdie (Windows :) ). Собственно сам скриптик я написал - вот он:
#!/usr/bin/env python
# -*-coding: cp1251 -*-

import win32api
import os
import time
import subprocess

ZIPPATH='C:\\Program Files\\7-Zip\\7z.exe'

def spacechk(diskletter):
"""
Функция определяющая свободное место на диске в байтах
Использование:
spacechk(diskletter), где
diskletter - буква диска в формате "c:\\";
"""
# Получаем данные о диске - количество секторов в кластере(a), количество
# байтов в секторе(b), количество сободных кластеров(c), общее кол-во
# кластеров в диске(d)
a,b,c,d = win32api.GetDiskFreeSpace(diskletter)
return (a*b*c)

def findfldt(dirpath, newest=False):
"""
Функция ищущая самый старый/новый файл в заданной папке
Использование:
findfldt(dirpath, [newest]), где
dirpath - полный путь до папки, в которой производится поиск;
newest - переключатель выбирающий какой файл искать - самый старый или
самый новый. Значение False соответствует самому старому, True - самому
новому. По умолчанию ищется самый старый;
"""
fltimes = []
# Проходимся по всем файлам в заданной папке
for ph,dirs,files in os.walk(dirpath):
for fl in files:
# Для каждого из файлов определяем полный путь
fullp = os.path.join(ph,fl)
# Собираем список файлов в формате (время_в_unixtime,полный_путь)
fltimes.append( (os.path.getmtime(fullp),fullp) )
# Возвращаем первый файл из отсортированного списка.
if fltimes:
return sorted(fltimes,reverse=newest)[0]
# Если данная папка пуста, то возвращаем размер=0, имя_файла = ''
else:
return (0,'')

def crtarch(path,pathtoarch,prefix=''):
"""
Функция создающая архив типа zip из заданной папки/файла
Использование:
crtarch(path,pathtoarch,[prefix]), где
path - путь к папке/файлу для архивации;
pathtoarch - путь по которому надо положить архив;
prefix - Имя архива является датой типа 2009-12-25_15:50.zip Значение этой
переменной будет поставлено перед датой - backup_2009-12-25_15:50.zip;
"""
# Создаем имя для архива
if prefix:
nm = prefix + '_' + time.strftime('%Y-%m-%d_%H-%M')
else:
nm = time.strftime('%Y-%m-%d_%H-%M')
# Получаем полный путь к архиву
arch = os.path.join(pathtoarch,nm) + '.zip'
# Создаем архив по заданному пути, используя сторонюю программу
subprocess.call('"%s" a "%s" "%s"' % (ZIPPATH, arch, path) )

def rmoldestfl(dsk,path,growth=10):
"""
Функция освобождающая место на диске под новый архив
Использование:
rmoldestfl(dsk,path,[growth]), где
dsk - буква диска в формате "c:\\";
path - путь к папке из которой следует удалать старые копии архивов,
ориентируясь на размер последней копии;
growth - Коэф прироста бэкапа за время с момента последнего копирования,
в %(целое число). По умолчанию - 10%;
"""
# Определяем пустое место на диске
freesp = spacechk(dsk)
# Определяем размер последнего архива
flsz,flname = findfldt(path, True)
# До тех пор пока место на диске меньше размера последнего архива с учетом
# коэф прироста
while freesp < (flsz + flsz*growth/100.):
# Находим самый старый архив
oldfl = findfldt(path)
# И удаляем его
os.remove(oldfl[1])
freesp = spacechk(dsk)
flsz,flname = findfldt(path, True)

if __name__ == '__main__':
# rmoldestfl('F:\\','F:\\Backup')
# crtarch('D:\\Documents\\242\\Проекты','F:\\Backup','projects')
print findfldt('D:\\Documents\\242\\Проекты')
Начал я его тестировать (собственно вы видите что в основной секции функции нужные для запуска закомментированы - используется только одна - findfldt('D:\\Documents\\242\\Проекты') ). Запустил поиск старых/новых файлов по целевому каталогу для архивирования (в реальнности так работать не должно). Получил такую вот ошибку -
IDLE 2.6.1      ==== No Subprocess ====
>>>
Traceback (most recent call last):
File "F:\pybkpdoc.py", line 97, in <module>
print findfldt('D:\\Documents\\242\\Проекты')
File "F:\pybkpdoc.py", line 41, in findfldt
fltimes.append( (os.path.getmtime(fullp),fullp) )
File "C:\Python26\lib\genericpath.py", line 54, in getmtime
return os.stat(filename).st_mtime
WindowsError: [Error 206] : 'D:\\Documents\\242\\\xcf\xf0\xee\xe5\xea\xf2\xfb\\\xc2\xd3\xc7\xdb\\\xcc\xc3\xd3\xca\xc8 \xf2\xe5\xe0\xf2\xf0 \xd5\xe8\xec\xea\xe8\\\xce\xf2\xef\xf0\xe0\xe2\xea\xe0\\\xc8\xed\xf2\xe5\xf5\\\xcc\xc3\xd3\xca\xc8 \xd5\xe8\xec\xea\xe8 30-01-09\\\xf1\xe2\xe5\xf2-\xec\xe5\xf5\xe0\xed\xe8\xea\xe0\\\xcc\xc3\xd3\xca\xc8 \xd2\xca\xc7 \xd5\xee\xf0\xe5\xee\xe3\xf0\xe0\xf4\xe8\xf7\xe5\xf1\xea\xe8\xe9 \xe7\xe0\xeb \xd1\xe2\xe5\xf2 \xdd\xeb\xe5\xea\xf2\xf0\xee\xec\xe5\xf5\xe0\xed\xe8\xea\xe0\\UKI-EO3.07.E7_Shema_razm-ya_oborud-ya._Uroven_svetoregulyatornoi_i_sofitov_repeticionnogo_horeograficheskogo_zala.dwg'
>>>
После некоторого гугления было выяснено что
Код ошибки: 206 (0x00CE)
Имя файла или его расширение имеет слишком большую длину.
Соответственно хотелось бы понимать в чем причина - не хотелось бы чтобы эта ошибка вылетала при архивировании (т е не хотелось бы иметь битые резервные копии). Вроде я подстраховался как мог, перевесив все архивирование на 7z - но все таки.

Попробую ночью запустить этот скрипт (днем все будет тормозить - там 40Гб) - посмотрю как работает.

Всем спасибо
Zubchick
убери русский из путей

ЗЫ
#!/usr/bin/env python
ыыы)
Alex2ndr
Zubchick
убери русский из путей
Это невозможно. Папки создают пользователи и используют и русский и пробелы и все что угодно.
Zubchick
значит разбирайся с кодировками :)
Alex2ndr
Zubchick
значит разбирайся с кодировками :)
Слишком длинный путь получается потому что в utf-8 кирилица отображается 3 символами? В этом дело?
Zubchick
ну очевидно да, я еле домотал до конца)
Alex2ndr
Zubchick
ну очевидно да, я еле домотал до конца)
Просто ошибка гласит именно "Имя файла или его расширение имеет слишком большую длину.". Имя действительно длинное - но винда ведь дала его создать и работать с этим документом можно.
expee
Читаем: http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maxpath
Alex2ndr
Если кому интересно полный путь выглядит так -
D:\Documents\242\Проекты\ВУЗЫ\МГУКИ театр Химки\Исходные\ФОТОН\03-03-08\МГУКИ ТКЗ Хореографический зал Свет Электромеханика часть 1\UKI-EO3.07.E7_Shema_razm-ya_oborud-ya._Uroven_svetoregulyatornoi_i_sofitov_repeticionnogo_horeograficheskogo_zala.dwg
И это еще не самый длинный путь и имя файла которые там есть.
Slon
Это не linux, это винда =))) От держи =)

http://msdn.microsoft.com/en-us/library/ee681827%28VS.85%29.aspx#limits

Максимальная длина имени файла — 256 символов.
Максимальная длина пути — 32,767 символов Юникода, при этом каждый компонент пути не превышает 255 символов.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB