none
Преобразования имени файла в URL-совместимое имя (ну или как то так) RRS feed

  • Вопрос

  • Здравствуйте. Для личных нужд поднял у себя микро файло обменник и написал под него программу следующего содержания:

    using System.IO;
    using System.Windows.Forms;
    
    namespace CopyToHost
    {
        class Program
        {
            [System.STAThread]
            static void Main(string[] args)
            {
                try
                {
                    FileInfo fi = new FileInfo(args[0]);
    
                    if (fi.FullName == args[0])
                    {
                        Clipboard.SetText(@"http://91.215.77.168/" + fi.Name);
                    }
                    else
                    {
                        fi.CopyTo("D:\\Sites\\Files\\" + fi.Name, true);
                        Clipboard.SetText(@"http://91.215.77.168/" + fi.Name);
                    }
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Пичаль-ня~");
                }
            }
        }
    }

    Прога висит в меню shell:SendTo. Суть в том, что файлы с именем из одного слова открываются нормально, а если в имени есть пробел - то плохо (точнее чуть менее, чем никак). Есть ли функция преобразования имени в файла в более понятное для браузеров?

    DreamSpark Premium User


Ответы

  • Скорее всего универсального метода типа ConvertToStandartURL нет (по крайней мере я такой не нашел), плюс спецификация не запрещает использование пробела в URL (опять же знаю примеры где адрес с пробелом исправно работает, он просто заменяется автоматом на символ %20).

    Вывод - если в вашем случае пробел проблема, то куда проще заменить строку

    Clipboard.SetText(@"http://91.215.77.168/" + fi.Name);

    на

    Clipboard.SetText((@"http://91.215.77.168/" + fi.Name).Replae(" ", "_"));

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!



    • Изменено LXGDARKEditor 10 мая 2012 г. 16:41
    • Помечено в качестве ответа asdfxcbneftyherwe 10 мая 2012 г. 17:02
    Отвечающий
    • Помечено в качестве ответа asdfxcbneftyherwe 10 мая 2012 г. 17:32
    Отвечающий
  • namespace CopyToHost
    {
        class Program
        {
            [System.STAThread]
            static void Main(string[] args)
            {
                try
                {
                    FileInfo fi = new FileInfo(args[0]);
    
                    if (fi.FullName == ("D:\\Sites\\Files\\" + fi.Name.Replace(' ', '_')))
                    {
                        Clipboard.SetText(@"http://91.215.77.168/" + fi.Name);
                    }
                    else
                    {
                        string name = fi.Name.Replace(' ', '_');
                        File.Copy(fi.FullName, "D:\\Sites\\Files\\" + name);
                        Clipboard.SetText(@"http://91.215.77.168/" + name);
                    }
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Пичаль-ня~");
                }
            }
        }
    }

    Вот так вот сделал :)

    DreamSpark Premium User

    • Помечено в качестве ответа asdfxcbneftyherwe 10 мая 2012 г. 17:02
  • Разобрался. HttpUtility.EncodePathUrl() нужно вызывать для всего, кроме имени протокола и доменного имени сервера.

    DreamSpark Premium User

    • Помечено в качестве ответа asdfxcbneftyherwe 10 мая 2012 г. 18:54

Все ответы

  • Самым быстрым решением будет использовать знак нижнего подчёркивания в именах файлов вместо пробелов.
    Модератор
  • Мне в день приходится обмениваться огромной пачкой файлов, переименовывать их все - очень плохой вариант. Знаю, что должна быть функция для этого, подсознательно думаю, что она в System.Web; а вот как она называется и где она именно лежит - я не знаю. :)

    Или Вы имеете в виду на лету их переименовывать, при копировании?


    DreamSpark Premium User


  • "Или Вы имеете в виду на лету их переименовывать, при копировании?" - можно и так поступить, тоже вариант.
    Модератор
  • Насколько понял Вы собираетесь передавать свои файлы по Http на сервер, так что ли?
    Модератор
  • Нет, у меня на компьютере сервер, а программа копирует файл из заданной локации в расшаренную папку, и в буфер обмена копирует ссылку на файл. :)

    DreamSpark Premium User

  • Скорее всего универсального метода типа ConvertToStandartURL нет (по крайней мере я такой не нашел), плюс спецификация не запрещает использование пробела в URL (опять же знаю примеры где адрес с пробелом исправно работает, он просто заменяется автоматом на символ %20).

    Вывод - если в вашем случае пробел проблема, то куда проще заменить строку

    Clipboard.SetText(@"http://91.215.77.168/" + fi.Name);

    на

    Clipboard.SetText((@"http://91.215.77.168/" + fi.Name).Replae(" ", "_"));

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!



    • Изменено LXGDARKEditor 10 мая 2012 г. 16:41
    • Помечено в качестве ответа asdfxcbneftyherwe 10 мая 2012 г. 17:02
    Отвечающий
  • namespace CopyToHost
    {
        class Program
        {
            [System.STAThread]
            static void Main(string[] args)
            {
                try
                {
                    FileInfo fi = new FileInfo(args[0]);
    
                    if (fi.FullName == ("D:\\Sites\\Files\\" + fi.Name.Replace(' ', '_')))
                    {
                        Clipboard.SetText(@"http://91.215.77.168/" + fi.Name);
                    }
                    else
                    {
                        string name = fi.Name.Replace(' ', '_');
                        File.Copy(fi.FullName, "D:\\Sites\\Files\\" + name);
                        Clipboard.SetText(@"http://91.215.77.168/" + name);
                    }
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Пичаль-ня~");
                }
            }
        }
    }

    Вот так вот сделал :)

    DreamSpark Premium User

    • Помечено в качестве ответа asdfxcbneftyherwe 10 мая 2012 г. 17:02
    • Помечено в качестве ответа asdfxcbneftyherwe 10 мая 2012 г. 17:32
    Отвечающий
  • HttpUtility.UrlEncode

    Вот код приложения, в итоге в буфере бред оказывается, а не рабочая ссылка. Или http:// передавать не нужно?

    using System.IO;
    using System.Windows.Forms;
    using System.Web;
    
    namespace CopyToHost
    {
        class Program
        {
            [System.STAThread]
            static void Main(string[] args)
            {
                try
                {
                    FileInfo fi = new FileInfo(args[0]);
    
                    if (fi.FullName == "D:\\Sites\\Files\\" + fi.Name)
                    {
                        Clipboard.SetText(HttpUtility.UrlEncode("http://91.215.77.168/" + fi.Name));
                    }
                    else
                    {
                        File.Copy(fi.FullName, "D:\\Sites\\Files\\" + fi.Name);
                        Clipboard.SetText(HttpUtility.UrlEncode("http://91.215.77.168/" + fi.Name));
                    }
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message, "Пичаль-ня~");
                }
            }
        }
    }
    

    профиль .NET 4.0 - полный (в клиентском вроде нету System.Web), сама ссылка на либу подключена. Прога консольная.


    DreamSpark Premium User

  • Разобрался. HttpUtility.EncodePathUrl() нужно вызывать для всего, кроме имени протокола и доменного имени сервера.

    DreamSpark Premium User

    • Помечено в качестве ответа asdfxcbneftyherwe 10 мая 2012 г. 18:54
  • Я потестил этот класс (странно правда что в проект WPF 4 его пришлось добавлять ручным поиском dll, наверное просто устарел) и он заменяет пробел знаком +.

    Проблема была у вас в пробелах и она легко решалась через Replace, так зачем заморочки с этим классом?


    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    Отвечающий
  • Кстати вот еще на вот это посмотрите. Этот класс не делает фактической замены символов, а скорее делает подставку кодов. Как я писал вше пробел это %20. То есть в можете оставить имя файла без изменений, а ссылку обработать, получив на входе рабочую (даже если в имени файла есть пробелы)

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    Отвечающий
  • У меня так и делается в конечной версии, вот код:

    try
                {
                    FileInfo fi = new FileInfo(args[0]);
    
                    if (fi.FullName == "D:\\Sites\\Files\\" + fi.Name)
                    {
                        Clipboard.SetText("http://91.215.77.168/" + HttpUtility.UrlPathEncode(fi.Name));
                    }
                    else
                    {
                        fi.CopyTo("D:\\Sites\\Files\\" + fi.Name, true);
                        Clipboard.SetText("http://91.215.77.168/" + HttpUtility.UrlPathEncode(fi.Name));
                    }
                }

    В моём случае энкодится только имя файла, в случае более длинного пути с русскими папками, нужно энкодить все, кроме доменного имени.

    DreamSpark Premium User