Использование file.move для переименования новых файлов в C # - PullRequest
0 голосов
/ 14 мая 2018

Я очень новичок в кодировании, и я пишу приложение, которое будет переименовывать файлы добавляя миллисекунды к существующему имени файла файлов, которые были отсканированы с MFD. Папка является общей папкой, и переименованный файл должен оставаться в ней и не копироваться в другом месте.

После долгих поисков я знаю, что File.Move - это мой путь вперед, однако я не могу заставить его работать.

Вот мой код:

private void MonitorToggle_Click(object sender, EventArgs e)
    {
       // Create a new FileSystemWatcher object.
        FileSystemWatcher fsWatcher = new FileSystemWatcher();

        switch (MonitorToggle.Text)
        {
            // Start Monitoring…
            case startMonitoring:
                if (!FilePathField.Text.Equals(String.Empty))
                {
                    //Set the watched folder path equal to the file path variable
                    fsWatcher.Path = FilePathField.Text;

                    // Set Filter.
                    fsWatcher.Filter = (FileTypeField.Text.Equals(String.Empty))? "*.*" : FileTypeField.Text;

                    // Monitor files and subdirectories.
                    fsWatcher.IncludeSubdirectories = true;

                    // Monitor all changes specified in the NotifyFilters.
                    fsWatcher.NotifyFilter = NotifyFilters.LastWrite;

                    fsWatcher.EnableRaisingEvents = true;

                    // Raise Event handlers.
                    fsWatcher.Changed += new FileSystemEventHandler(OnChanged);
                    fsWatcher.Created += new FileSystemEventHandler(OnCreated);
                }
                else
                {
                    MessageBox.Show("Please select a folder to monitor.", "Warning",MessageBoxButtons.OK, MessageBoxIcon.Warning );
                }
                break;

            // Stop Monitoring…
            case stopMonitoring:
            default:

                fsWatcher.EnableRaisingEvents = false;
                fsWatcher = null;
                break;
        }

    }

    public void OnChanged (object sender, FileSystemEventArgs e)
    {
        FileInfo file = new FileInfo(e.Name);
        string dateStamp = DateTime.Now.ToString("fff");
        string fName = file.Name;
        string newFile = string.Concat(fName, dateStamp);
        File.Move(fName,newFile);            
    }

    public void OnCreated(object sender, FileSystemEventArgs e)
    {
        FileInfo file = new FileInfo(e.Name);
        string dateStamp = DateTime.Now.ToString("fff");
        string fName = file.Name;
        string newFile = string.Concat(fName, dateStamp);
        File.Move(fName, newFile);
    }

    private void BrowseButton_Click(object sender, EventArgs e)
    {
        // Create FolderBrowserDialog object.
        FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
        // Show a button to create a new folder.
        folderBrowserDialog.ShowNewFolderButton = true;
        DialogResult dialogResult = folderBrowserDialog.ShowDialog();
        // Get selected path from FolderBrowserDialog control.
        if (dialogResult == DialogResult.OK)
        {
            FilePathField.Text = folderBrowserDialog.SelectedPath;
            Environment.SpecialFolder root = folderBrowserDialog.RootFolder;
        }
    }

Всякий раз, когда я создаю новый файл в папке, которую я смотрю, он абсолютно ничего не делает. Сначала я подумал, что это может быть из-за того, что у меня был только метод «OnCreated», поэтому я скопировал его в метод «OnChanged» (я не был уверен, что если скопировать существующий файл в папку, он считается «созданным», но Мне не повезло).

Из интереса, я также получаю исключение, если я не указываю тип в фильтре, но это гораздо менее актуально в минуту.

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

1 Ответ

0 голосов
/ 14 мая 2018

Есть несколько проблем с вашим кодом.

Во-первых, вы должны использовать e.FullPath вместо e.Name, в противном случае код попытается переименовать файл в текущем каталоге, а не в просматриваемый каталог..

Во-вторых, чтобы получить событие Created, вы должны включить NotifyFilters.FileName.

Однако это вам мало поможет, поскольку файл заблокирован в созданных и измененных событиях дофайл скопирован, поэтому вы получите исключение.Кроме того, вы, вероятно, получите более одного события Changed (в моих тестах я всегда получал два события, независимо от размера файла, но оно может различаться в разных версиях Windows или .Net framework).

Чтобы исправить это, вы можете использовать таймеры или потоки для выполнения задачи.Вот пример использования потока ThreadPool.Всякий раз, когда создается, запускается, вы создаете новую тему.В ветке вы проверяете, заблокирован ли файл (пытается открыть файл), а когда файл разблокирован, выполните переименование.

public class FileMon
{
    public static void Run()
    {
        FileSystemWatcher fsWatcher = new FileSystemWatcher();
        fsWatcher.Path = @"C:\Test\";        
        fsWatcher.Filter = "*.*" ;
        fsWatcher.IncludeSubdirectories = true;

        // Monitor all changes specified in the NotifyFilters.
        fsWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName ;

        fsWatcher.EnableRaisingEvents = true;

        // Raise Event handlers.
        fsWatcher.Changed += OnChanged;
        fsWatcher.Created += OnCreated;
        Console.WriteLine("[Enter] to end"); Console.ReadLine();
        fsWatcher.EnableRaisingEvents = false;
    }

    static void Worker(object state)
    {
        FileSystemEventArgs fsArgs = state as FileSystemEventArgs;
        bool done = false;
        FileInfo fi = new FileInfo(fsArgs.FullPath);

        do
        {
            try
            {
                using (File.Open(fsArgs.FullPath, FileMode.Open))
                {
                    done = true;
                }
            }
            catch
            {
                done = false;
            }
            Thread.Sleep(1000);
        } while (!done);
        Console.WriteLine("DOne");
        string dateStamp = DateTime.Now.ToString("fff");
        string fName = fi.FullName;
        string newFile = fsArgs.FullPath + dateStamp;
        File.Move(fsArgs.FullPath, newFile);
    }

    private static void OnCreated(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine($"Created {e.ChangeType} : {e.Name}");
        ThreadPool.QueueUserWorkItem(Worker, e);
    }

    static void OnChanged(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine($"{e.ChangeType} : {e.FullPath}");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...