Member 12692000 Ответов: 3

Новичок борется с простой программой?


Всем привет
Я пытаюсь создать простую программу копирования файлов для копирования файлов *.tif из одного места from_path до другого to_path.
Скажем, если from_path это что-то вроде "D:\database", то содержимое внутри него выглядит так
"D:\database\12345\tiffile1.tif, tiffile2.tif ... etc"
"D:\database\12335\tiffile1.tif, tiffile2.tif ... etc"

так далее...
а если ... to_path это что-то вроде "E:\Jobs", то содержимое внутри него выглядит так
"E:\Jobs\12334-12366\1\xml\12345.xml"
"E:\Jobs\13334-12666\15\xml\12335.xml"

Я хочу скопировать все тиф файлы из папки в from_path чье имя точно совпадает с именем xml - файла в to_path
Ниже приведен метод, который я пытался реализовать
1) получить все файлы *.xml из to_path
2) получить имя и полный путь к xml-файлу
3) проверьте, является ли папка с тем же именем, что и xml-файл в from_path существовать
4) если да, то скопируйте все тиф файлы из него и вставьте в папку с именем xml, используя полный путь на шаге 2.
Я пробовал что-то вроде ниже, но я получаю Система.UnauthorizedAccessException: доступ к пути D:\database\12335-это отрицается.
Кроме того, targetLoc показывает путь к файлу в каталоге my programs bin.

Что я уже пробовал:

string to_path=textBox1.Text;
string from_path=textBox2.Text;
DirectoryInfo diCopyFrom = new DirectoryInfo(from_path);
DirectoryInfo diCopyTo = new DirectoryInfo(to_path);
FileInfo[] xmlFiles = diCopyTo.GetFiles("*.xml",SearchOption.AllDirectories);
foreach (FileInfo xmlFile in xmlFiles)
{
	var xmlDir = Path.GetFileNameWithoutExtension(xmlFile.Name);
	var targetLoc=Path.GetFullPath(xmlFile.Name);
	var tifLoc = Directory.GetDirectories(from_path,xmlDir,SearchOption.AllDirectories).FirstOrDefault();
	if (Directory.Exists(tifLoc.ToString()))
		File.Copy(tifLoc, targetLoc, true);
}
MessageBox.Show("Finished")

BillWoodruff

начните здесь: https://stackoverflow.com/questions/8821410/why-is-access-to-the-path-denied

описание вашей проблемы немного сбивает с толку: вы упоминаете "вставить", которое является пользовательским действием в Windows со стороны пользователей, но здесь вы используете код.

Member 12692000

на сайте StackOverflow статьи не помогли решить проблему...есть некоторые проблемы с логикой в коде? Мне трудно понять, хотя эта программа должна была быть легкой и простой.

Member 12692000

Я имел в виду скопировать файлы в нужную папку...моя вина

3 Ответов

Рейтинг:
2

BillWoodruff

Посмотрите, исправит ли это проблему доступа к файлам:

1. добавить в свои приложения с помощью заявления:

using System.Security.Permissions;
2. Добавьте этот атрибут чуть выше метода(ов), где вы сейчас получаете ошибки отказа в доступе:
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
private void MyFileAccessMethod(?,?,?)
{
}


Member 12692000

Это не решает проблему...ошибки все еще есть...

BillWoodruff

Кроме того, попробуйте запустить Visual Studio от имени администратора. Есть ли Drive 'D в сети ?

Рейтинг:
12

Richard Deeming

Здесь есть несколько моментов путаницы:

1) Path.GetFullPath(xmlFile.Name) будет объединять имя XML - файла с текущий рабочий каталог. Эта воля нет быть таким же, как полный путь к XML-файлу, который вы можете получить с помощью xmlFile.FullName;

2) на самом деле вам не нужен полный путь к XML-файлу; поскольку вы пытаетесь скопировать другие файлы в этот путь, вам нужен путь к родительскому каталогу. Вы можете получить это с помощью xmlFile.DirectoryName;

3) с tifLoc это каталог, который вы не можете использовать File.Copy чтобы скопировать его в другом месте. К сожалению, вам нужно скопировать отдельные файлы отдельно.

4) Directory.GetDirectories(...).FirstOrDefault() будет возвращать null если каталог не существует. В этом случае вы получите NullReferenceException на следующей линии, когда вы пытаетесь позвонить .ToString() по возвращении string ценность.

Кроме того, вы, вероятно, захотите использовать EnumerateFiles и EnumerateDirectories вместо их Get* аналоги, особенно если есть много файлов для обработки. То Get* версии должны загрузить все совпадения в память, прежде чем вы сможете начать их обработку, в то время как Enumerate* версии позволяют начать обработку сразу же после обнаружения первого совпадения.

Что-то вроде этого должно сработать:

DirectoryInfo diCopyFrom = new DirectoryInfo(textBox1.Text);
DirectoryInfo diCopyTo = new DirectoryInfo(textBox2.Text);

foreach (FileInfo xmlFile in diCopyTo.EnumerateFiles("*.xml", SearchOption.AllDirectories))
{
    // Eg:
    // xmlFile = "E:\Jobs\12334-12366\1\xml\12345.xml"
    
    string tifDirectoryName = Path.GetFileNameWithoutExtension(xmlFile.Name);
    // tifDirectoryName = "12345"
    
    DirectoryInfo sourceDirectory = diCopyFrom.EnumerateDirectories(tifDirectoryName, SearchOption.AllDirectories).FirstOrDefault();
    if (sourceDirectory != null)
    {
        string destinationDirectoryName = xmlFile.DirectoryName;
        // destinationDirectoryName = "E:\Jobs\12334-12366\1\xml\"
        
        foreach (FileInfo tifFile in sourceDirectory.EnumerateFiles("*.tif"))
        {
            // tifFile = "D:\database\12345\tiffile1.tif"
            
            string destFileName = Path.Combine(destinationDirectoryName, tifFile.Name);
            // destFileName = "E:\Jobs\12334-12366\1\xml\tiffile1.tif"
            
            tifFile.CopyTo(destFileName, true);
        }
    }
}


Member 12692000

Спасибо Ричард :D

Рейтинг:
1

OriginalGriff

Начните с отладчика: поместите точку останова в первую строку метода и запустите код через отладчик. Затем посмотрите на свой код и на свои данные и определите, что должно произойти вручную. Затем по одному шагу в каждой строке проверяйте, что то, что вы ожидали, произойдет именно так, как и произошло. Когда это не так, тогда у вас есть проблема, и вы можете вернуться назад (или запустить ее снова и посмотреть более внимательно), чтобы выяснить, почему.

Извините, но мы не можем сделать это для вас, потому что у нас нет ваших файлов или структур папок - время для вас, чтобы изучить новый (и очень, очень полезный) навык: отладка!


Member 12692000

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

В любом случае спасибо за Ваше мнение...

OriginalGriff

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

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

Только вы можете это сделать: только у вас есть доступ к машине, на которой вы запускаете этот код...
Так что оставь свое отношение, пожалуйста.

Member 12692000

Я не показываю никакого отношения...расслабься, чувак.
Я понял твою точку зрения.

OriginalGriff