2010-01-05 3 views
10

У меня есть приложение, которое просматривает некоторые файлы для старых данных. Чтобы убедиться, что мы не повредили хорошие проекты, я копирую файлы во временное место. Некоторые из каталогов, которые я проверяю, это каталоги исходного кода, и у них есть папки .svn. Мы используем Subversion для управления нашим кодом.UnauthorizedAccessException для вновь созданных файлов

Как только я просмотрел все файлы, я хочу удалить временный кеш. Звучит просто, не так ли?

По какой-то причине все мои .svn-каталоги не будут удаляться из кеша. Они разбивают приложение.

По причинам (слишком глубоко, чтобы войти сюда), я должен использовать временную папку, поэтому просто «сканировать исходный файл» не может быть и речи по политическим причинам.

Я могу войти в проводник и удалить их. Нет проблем. Нет предупреждений. Просто удаляет. Но сбой кода с «Access to {file} запрещен». Я нахожусь наедине с этим, поэтому любая помощь будет оценена.

Хотя я упростил функцию LITTLE ради вашего здравомыслия, код ДЕЙСТВИТЕЛЬНО об этом прост.

List<string> tmpCacheManifest = new List<string>(); 
string oldRootPath = "C:\\some\\known\\directory\\"; 
string tempPath = "C:\\temp\\cache\\"; 

foreach (string file in ListOfFilesToScan) 
{ 
    string newFile = file.Replace(oldRootPath, tempPath); 

    // This works just fine. 
    File.Copy(file, newFile); 

    tmpCacheManifest.add(newFile); 
} 

// ... do some stuff to the cache to verify what I need. 


// Okay.. I'm done.. Delete the cache. 
foreach (string file in tmpCacheManifest) 
{ 
    // CRASH! 
    File.Delete(file); 
} 

* Update *: Исключение составляет UnauthorizedAccessException. Текст - «Доступ к пути» C: \ temp \ cache \ some-sub-dirs \ .svn \ entries 'отрицается. "

Это происходит под XP, XP-Pro и Windows 7.

* Update 2 * Ни один из моих проверки даже не пытается смотреть на подрывных файлов. Мне они действительно нужны. Это часть политического дерьма. Я должен показать, что КАЖДЫЙ файл был скопирован ... если он был отсканирован или нет.

И я понимаю, что обычные подозреваемые для File.Delete. Я понимаю, что означает UnauthorizedAccessException. У меня нет доступа. Это без проблем. Но я просто скопировал файл. Как я могу NOT есть доступ к файлу?

* Обновление 3 * Ответ был включен в «только для чтения». Вот код, который я использовал, чтобы исправить это:

foreach (string file in ListOfFilesToScan) 
{ 
    string newFile = file.Replace(oldRootPath, tempPath); 

    // This works just fine. 
    File.Copy(file, newFile); 

    //// NEW CODE //// 
    // Clear any "Read-Only" flags 
    FileInfo fi3 = new FileInfo(fn); 
    if ((fi3.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) 
    { 
     fi3.Attributes = (FileAttributes)(Convert.ToInt32(fi3.Attributes) - Convert.ToInt32(FileAttributes.ReadOnly)); 
    } 



    tmpCacheManifest.add(newFile); 
} 

// ... do some stuff to the cache to verify what I need. 

+3

Зачем? Может быть заблокирован файл. – 2010-01-05 16:21:28

+0

File.Delete может вызывать как минимум семь разных типов исключений. Какой из них вы получаете? –

+0

@Roboto, Вы имеете в виду: WTE? TCBAFL? –

ответ

12

Насколько я помню, Subversion отмечает файлы в своих подкаталогах .svn как доступные только для чтения.

Попробуйте сбросить атрибут только для чтения перед удалением файла. Я не знаю ни C#, но быстрый Google предполагает, что это может сделать трюк:

File.SetAttributes(file, FileAttributes.Normal); 
+1

Я протестировал это, и из всех предложений до сих пор это единственное, что фактически вызвало исключение! – Justin

+0

Хороший звонок! Я не считал «Только для чтения». Тем не менее, он по-прежнему вызывает исключение. Я действительно собираюсь что-то придумать. =) – Jerry

+0

GOT IT !! Наконец ... вторая авария была вызвана другой странностью, а не этой проблемой. – Jerry

-2

Не понимая, что вы хотите сделать так много, но как насчет chmoding это 777 или 775.: -/

Edit:

Заметил вас на окнах. Вам нужно будет изменить разрешения. Не знаю, как это делают окна: -/

0

Прежде всего: «Сбой» означает исключение, не так ли? Который из? Можете ли вы его поймать и показать?

Вторая вещь: Вы копируете хранилища подрывной деятельности, хотя вам не нужны метаданные subversion? Вот что такое svn export (нет .svn-каталога в целевой).

Ответ на первый вопрос - это то, что вам действительно нужно предоставить. Возможно, что-то захватывает .svn и блокирует некоторые файлы. TortoiseSVN может быть (чтобы дать вам красивые иконки наложения ...)?

2

Единственная проблема, которую я вижу бы в этой части:

// ... do some stuff to the cache to verify what I need.

Если вы открыть файл и забыть закрыть его, вы по-прежнему имеют эксклюзивный доступ к нему, и, таким образом, не может удалить это позже.

+0

Согласовано. Если вы имеете дело с объектами FileStream, обязательно вызывайте 'Close' на них (что вызывает' Dispose'). Еще лучше было бы просто обернуть их в «использование» блоков. –

+2

Это не будет причиной - если вы это сделаете, вы не позволите другим процессам удалять файл, однако, если тот же процесс пытается удалить файл, тогда нет проблем, поскольку дескриптор/блокировка принадлежит одному и тому же процессу. Я тестировал это, и это не вызывает исключения. – Justin

2

Похоже, у вас нет доступа для удаления файла ...

system.io.file.delete

выше ссылка говорит, что вы получите, когда UnauthorizedAccessException:

Вызывающий не имеет требуемого разрешение.

-or-

Путь - это каталог.

-или-

путь, указанный файл только для чтения.

Это один из тех.

+0

У него должен быть доступ к удалению файла, поскольку он имел доступ для создания файла в первую очередь. – Justin

+0

Ну, он сказал, что это исключение, которое бросает, я не знаю, как это сделать. –

1

Звучит как проблема с разрешениями. Tricky, хотя у вас, очевидно, есть доступ на запись, если File.Copy уже работает.

Единственное, что я мог придумать, это файл, в котором все еще есть дескриптор (как другие предположили, возможно, в вашем материал в кэш часть).

+0

У него должен быть доступ к удалению файла, поскольку он имел доступ для создания файла в первую очередь. – Justin

+0

@ Kragen Я на самом деле уже заявил, что в своем ответе ... – James

0

Если папка содержит файлы только для чтения, Directory.Delete не удалит его и поднять исключение вы находитесь получение. Для будущих посетителей этой страницы, я нашел простое решение, которое не требует, чтобы мы рекурсии через все файлы и изменять их только для чтения атрибута:

Process.Start("cmd.exe", "/c " + @"rmdir /s/q C:\Test\TestDirectoryContainingReadOnlyFiles"); 

(немного изменить, чтобы не сгореть cmd на мгновение, которое доступно по всему Интернету)

Смежные вопросы