Potrzebuję solidnego i prostego sposobu na usunięcie nielegalnej ścieżki i znaków pliku z prostego ciągu. Użyłem poniższego kodu, ale wydaje się, że nic nie robi, czego mi brakuje?
using System;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string illegal = "\"M<>\"\\a/ry/ h**ad:>> a\\/:*?\"<>| li*tt|le|| la\"mb.?";
illegal = illegal.Trim(Path.GetInvalidFileNameChars());
illegal = illegal.Trim(Path.GetInvalidPathChars());
Console.WriteLine(illegal);
Console.ReadLine();
}
}
}
GetInvalidFileNameChars()
usunie rzeczy takie jak: \ etc ze ścieżek folderów.Path.GetInvalidPathChars()
wydaje się nie rozbierać*
ani?
Odpowiedzi:
Zamiast tego spróbuj czegoś takiego;
Ale muszę zgodzić się z komentarzami, prawdopodobnie spróbowałbym zająć się źródłem nielegalnych ścieżek, zamiast próbować przekształcić nielegalną ścieżkę w legalną, ale prawdopodobnie niezamierzoną.
Edycja: Lub potencjalnie „lepsze” rozwiązanie przy użyciu Regex.
Wciąż jednak pojawia się pytanie, dlaczego to robisz.
źródło
GetInvalidPathChars()
może zawierać postacie, któreGetInvalidFileNameChars()
tego nie zrobią. Nie przejmujesz się poprawnością w stosunku do „przedwczesnej” optymalizacji. Po prostu używasz złego kodu.Pierwotne pytanie „usuwać nielegalne znaki”:
Zamiast tego możesz je zastąpić:
Ta odpowiedź była w innym wątku autorstwa Ceres , bardzo podoba mi się, że jest schludna i prosta.
źródło
Używam Linq do czyszczenia nazw plików. Możesz łatwo to rozszerzyć, aby sprawdzić również prawidłowe ścieżki.
Aktualizacja
Niektóre komentarze wskazują, że ta metoda nie działa dla nich, dlatego zamieściłem link do fragmentu DotNetFiddle, abyś mógł sprawdzić poprawność metody.
https://dotnetfiddle.net/nw1SWY
źródło
var invalid = new HashSet<char>(Path.GetInvalidPathChars()); return new string(originalString.Where(s => !invalid.Contains(s)).ToArray())
. Wydajność prawdopodobnie nie jest świetna, ale to chyba nie ma znaczenia.Możesz usunąć nielegalne znaki przy użyciu Linq w następujący sposób:
EDYCJA
Tak to wygląda z wymaganą edycją wspomnianą w komentarzach:
źródło
Są to świetne rozwiązania, ale wszystkie na nich polegają
Path.GetInvalidFileNameChars
, co może nie być tak niezawodne, jak mogłoby się wydawać. Zwróć uwagę na następujące uwagi w dokumentacji MSDN naPath.GetInvalidFileNameChars
:Path.GetInvalidPathChars
Metoda nie jest lepsza . Zawiera dokładnie tę samą uwagę.źródło
W przypadku nazw plików:
Aby uzyskać pełne ścieżki:
Zauważ, że jeśli zamierzasz użyć tego jako funkcji bezpieczeństwa, bardziej niezawodnym podejściem byłoby rozwinięcie wszystkich ścieżek, a następnie sprawdzenie, czy podana przez użytkownika ścieżka jest rzeczywiście dzieckiem katalogu, do którego użytkownik powinien mieć dostęp.
źródło
Na początek Trim usuwa tylko znaki z początku lub końca łańcucha . Po drugie, powinieneś ocenić, czy naprawdę chcesz usunąć obraźliwe postacie, czy też szybko zawieść i powiadomić użytkownika, że jego nazwa pliku jest nieprawidłowa. Mój wybór jest ten drugi, ale moja odpowiedź powinna przynajmniej pokazać, jak robić rzeczy we właściwy sposób I w niewłaściwy sposób:
Pytanie StackOverflow pokazujące, jak sprawdzić, czy dany ciąg jest prawidłową nazwą pliku . Uwaga: możesz użyć wyrażenia regularnego z tego pytania, aby usunąć znaki z zamianą wyrażeń regularnych (jeśli naprawdę musisz to zrobić).
źródło
Najlepszym sposobem na usunięcie niedozwolonego znaku z danych wejściowych użytkownika jest zastąpienie niedozwolonego znaku przy użyciu klasy Regex, utworzenie metody w kodzie z tyłu lub sprawdzenie poprawności po stronie klienta za pomocą kontrolki RegularExpression.
LUB
źródło
Używam do tego wyrażeń regularnych. Po pierwsze, dynamicznie buduję wyrażenie regularne.
Następnie po prostu wywołuję removeInvalidChars.Replace, aby znaleźć i zamienić. Można to oczywiście rozszerzyć również na znaki ścieżki.
źródło
new Regex(String.Format("^(CON|PRN|AUX|NUL|CLOCK\$|COM[1-9]|LPT[1-9])(?=\..|$)|(^(\.+|\s+)$)|((\.+|\s+)$)|([{0}])", Regex.Escape(new String(Path.GetInvalidFileNameChars()))), RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.CultureInvariant);
Absolutnie wolę pomysł Jeffa Yatesa. Będzie działać idealnie, jeśli nieznacznie go zmodyfikujesz:
Ulepszenie polega na uniknięciu automatycznie generowanego wyrażenia regularnego.
źródło
Oto fragment kodu, który powinien pomóc w .NET 3 i nowszych wersjach.
źródło
Większość powyższych rozwiązań łączy niedozwolone znaki zarówno dla ścieżki, jak i nazwy pliku, co jest niepoprawne (nawet gdy oba wywołania obecnie zwracają ten sam zestaw znaków). Najpierw podzieliłem ścieżkę + nazwę pliku na ścieżkę i nazwę pliku, a następnie zastosowałem odpowiedni zestaw do jednego z nich, a następnie połączyłem je ponownie.
wvd_vegt
źródło
Jeśli usuniesz lub zastąpisz jednym znakiem nieprawidłowe znaki, możesz mieć kolizje:
Oto prosta metoda, aby tego uniknąć:
Wynik:
źródło
Rzuć wyjątek.
źródło
Napisałem tego potwora dla zabawy, pozwala ci to w obie strony:
źródło
Myślę, że o wiele łatwiej jest sprawdzić poprawność za pomocą wyrażenia regularnego i określić, które znaki są dozwolone, zamiast próbować sprawdzić wszystkie złe znaki. Zobacz te linki: http://www.c-sharpcorner.com/UploadFile/prasad_1/RegExpPSD12062005021717AM/RegExpPSD.aspx http://www.windowsdevcenter.com/pub/a/oreilly/windows/news/csharp_0101.html
Poszukaj też „edytora wyrażeń regularnych”, bardzo pomagają. Istnieje kilka, wokół których nawet wypisuje kod w c # dla ciebie.
źródło
Wydaje się, że jest to O (n) i nie wydaje zbyt dużo pamięci na ciągi znaków:
źródło
Przeglądając tutaj odpowiedzi, wszystkie ** wydają się wymagać użycia tablicy znaków niepoprawnych nazw plików.
To prawda, że może to być mikrooptymalizacja - ale z korzyścią dla każdego, kto może chcieć sprawdzić dużą liczbę wartości pod kątem poprawności nazw plików, warto zauważyć, że zbudowanie zestawu nieważnych znaków przyniesie znacznie lepszą wydajność.
Byłem bardzo zaskoczony (zszokowany) w przeszłości, jak szybko hashset (lub słownik) osiąga lepsze wyniki niż iteracja po liście. W przypadku łańcuchów jest to absurdalnie niska liczba (około 5-7 pozycji z pamięci). W przypadku większości innych prostych danych (odniesienia do obiektów, liczby itp.) Magiczna krzyżówka wydaje się zawierać około 20 elementów.
Na „liście” Path.InvalidFileNameChars znajduje się 40 nieprawidłowych znaków. Przeprowadziłem dzisiaj wyszukiwanie, a na StackOverflow znajduje się całkiem niezły test porównawczy, który pokazuje, że zestaw skrótów zajmie nieco ponad połowę czasu tablicy / listy dla 40 elementów: https://stackoverflow.com/a/10762995/949129
Oto klasa pomocnicza, której używam do dezynfekcji ścieżek. Zapominam teraz, dlaczego miałem w sobie fantazyjną opcję wymiany, ale jest to urocza premia.
Dodatkowa metoda premiowa „IsValidLocalPath” też :)
(** te, które nie używają wyrażeń regularnych)
źródło
Możesz wyraźnie użyć metody.
źródło
Nazwa pliku nie może zawierać znaków z
Path.GetInvalidPathChars()
,+
oraz#
symbole, nazwy i inne specyficzne. Wszystkie czeki połączyliśmy w jedną klasę:Metoda
GetValidFileName
zastępuje wszystkie niepoprawne dane_
.źródło
Jedna linijka do czyszczenia ciągu z jakichkolwiek niedozwolonych znaków dla nazewnictwa plików Windows:
źródło
źródło
Spowoduje to, że chcesz i unikniesz kolizji
źródło
Wydaje mi się, że na pytanie, na które nie ma jeszcze pełnej odpowiedzi ... Odpowiedzi opisują tylko czystą nazwę pliku LUB ścieżkę ... Oto moje rozwiązanie:
źródło
Stworzyłem metodę rozszerzenia, która łączy kilka sugestii:
Źródło:
źródło
Oto funkcja, która zastępuje wszystkie niedozwolone znaki w nazwie pliku znakiem zastępującym:
Na przykład znak podkreślenia może być użyty jako znak zastępczy:
źródło
Lub możesz po prostu zrobić
źródło