Czy konwersja ścieżek plików systemu Windows na ścieżki plików systemu Unix jest bezpieczna za pomocą prostej zamiany?

12

Powiedzmy na przykład, że miałem to tak, że wszystkie moje pliki zostaną przeniesione z komputera z systemem Windows na maszynę unix jako taką: C:\test\myFile.txtdo {somewhere}/test/myFile.txt(litera dysku jest w tym momencie nieistotna).

Obecnie nasza biblioteka narzędzi, którą sami napisaliśmy, udostępnia metodę polegającą na prostym zastąpieniu wszystkich ukośników odwrotnych ukośnikami:

public String normalizePath(String path) {
   return path.replaceAll("\\", "/");
}

Ukośniki są zastrzeżone i nie mogą być częścią nazwy pliku, dlatego struktura katalogów powinna zostać zachowana. Nie jestem jednak pewien, czy istnieją inne komplikacje między oknami i ścieżkami uniksowymi, o które mógłbym się martwić (np .: nazwy nie-ascii itp.)

MxLDevs
źródło
4
Uważaj tylko na spacje - umieszczanie spacji w nazwach folderów systemu Windows jest znacznie bardziej powszechne niż w nazwach katalogów unix. W szczególności „\ Program Files” cały czas mnie łapie. W zależności od tego, w jaki sposób korzystasz ze ścieżek, może być konieczne ucieczka spacji za pomocą „\”.
Rob
1
@delnan dla uproszczenia, ograniczmy zakres ścieżek, aby wykluczyć ścieżki zmiennych.
MxLDevs,
2
@MxyL Problem nie zniknie, gdy zaszyfrujesz ścieżkę zamiast używać zmiennej środowiskowej. Jeśli chcesz tylko ścieżki, która nie wybuchnie, powinieneś być w porządku. Jeśli chcesz mieć sensowną ścieżkę lub chcesz wchodzić w interakcje z innym oprogramowaniem (lub oczekiwaniami użytkownika ...), potrzebujesz połączeń na podstawie oceny ścieżki.
1
@delnan Skupiam się głównie na tworzeniu prawidłowej ścieżki, ale to dobra uwaga. Ścieżki, które przekształcam, powinny być na tyle proste, aby same w sobie miały znaczenie.
MxLDevs
3
Odwrotne ukośniki są dozwolone w nazwach plików w systemie Linux, więc zastąpienie odwrotnymi ukośnikami w ścieżce systemu Linux może dodać nieprawidłowe katalogi. Na przykład /foo\\barnie jest odpowiednikiem /foo/barw systemie Linux.

Odpowiedzi:

7

Tak, jeśli wykonasz zamianę tylko w systemie Windows i wyłączysz ją podczas uruchamiania w innych systemach.

Wykonanie zamiany na systemach uniksowych jest złe, ponieważ \jest prawidłowym znakiem w nazwie pliku lub katalogu na platformach uniksowych. Na tych platformach tylko NULi /są zabronione w nazwach plików i katalogów.

Ponadto niektóre funkcje interfejsu API systemu Windows (głównie funkcje niższego poziomu) nie zezwalają na stosowanie ukośników do przodu - należy stosować z nimi ukośniki odwrotne .

Demi
źródło
4

Tak, ale cała ta sprawa jest sporna. Java płynnie konwertuje ukośniki do ukośników w systemie Windows. Możesz po prostu użyć ukośników dla wszystkich ścieżek, które są zakodowane na stałe lub zapisane w konfiguracji i będzie działać na obu platformach.

Osobiście zawsze używać ukośnik nawet w systemie Windows, ponieważ jest to nie postać ucieczki. Niezależnie od tego, czy surowa ścieżka znajduje się w kodzie, czy na zewnątrz w pliku właściwości, koduję ją w ten sam sposób.

Spróbuj! Będzie to działać w systemie Windows. Oczywiście zmień rzeczywistą ścieżkę na coś, co istnieje, a użytkownik ma uprawnienia do czytania.

File f = new File("c:/some/path/file.txt");
if (!f.canRead()) {
  System.out.println("Uh oh, Snowman was wrong!");
}

Bonus: możesz nawet mieszać ukośniki na tej samej ścieżce!

File f = new File("c:/some\\path/file.txt");
if (!f.canRead()) {
  System.out.println("Uh oh, Snowman was wrong again!");
}

źródło
1
Jeśli przeczytasz całą moją odpowiedź, zobaczysz, gdzie mówię, że zawsze użycie separatora plików Unix będzie działało poprawnie w obu miejscach, nie jest wymagana konwersja.
Pytanie stwierdza, że pliki zostaną przesłane, i pozostawia otwarte, w jaki sposób są przechowywane nazwy plików . Do pytania dodałem komentarz z prośbą o wyjaśnienie tej kwestii. Na podstawie odpowiedzi odpowiednio zmienię swoją odpowiedź.
Jest mało prawdopodobne, aby program zawierał ręcznie wprowadzoną listę wszystkich przesyłanych plików. Znacznie bardziej prawdopodobne jest, że do automatycznego wyliczania plików używany jest jakiś zautomatyzowany mechanizm. Biorąc pod uwagę parametry problemu, jak podano w pytaniu, mechanizm ten zapewnia tradycyjne ścieżki w stylu Windows. W obecnej formie odpowiedź ta mówi OP, aby zamiast tego rozwiązał inny problem, nie mówiąc im, w jaki sposób, a nawet , że powinny przekształcić swój problem w inny problem.
Eliah Kagan
Proszę przeczytać mój poprzedni komentarz.
1
Windows rozpoznaje zarówno fowrard, jak i ukośniki odwrotne, i tak było od wczesnego MS-DOS. To znaczy, że każde jądro systemu operacyjnego Microsoft obsługuje separator ukośnika do przodu. Wcześni COMMAND.COMtłumacze mieli preferencje dotyczące czasu wykonywania: możesz skonfigurować, którego slashu interpreter użyje do drukowania i analizy.
Kaz
3

Kolejną komplikacją w systemie Windows jest to, że obsługuje on również notację UNC, a także tradycyjne litery dysków.

Dostęp do pliku na zdalnym serwerze plików można uzyskać jako \\server\sharename\path\filename.

Simon B.
źródło
1
Myślę, że jest to jedyny przytoczony problem, który w rzeczywistości stanowi problem dla tej aplikacji. Jeśli w grę wchodzą ścieżki UNC, nie można ich przekonwertować na ścieżkę uniksową.
Jules
2

Nie. Jest o wiele więcej rzeczy do przemyślenia niż tylko separator ścieżek (rzecz „\ vs /”). Jak wspomina Rob Y, istnieje sposób, w jaki obsługiwane są spacje i ich wysoka częstotliwość w systemie Windows. W obu środowiskach występują różne nielegalne postacie. Istnieje gotowość Unixa, aby pozwolić na prawie wszystko, gdy ucieka przed wiodącym „\”. Windows używa „” do radzenia sobie z osadzonymi przestrzeniami. Windows używa UCS-16, a Unix ASCII lub UTF-8.

itd. , itd. , itd.

Ale w przypadku wielu aplikacji, które mogą nakładać ograniczenia na ścieżki, którymi muszą manipulować, faktycznie można to zrobić tak, jak sugerujesz. I będzie działać w co najmniej dużej liczbie przypadków, po prostu nie we wszystkich.

Ross Patterson
źródło
1
Nie sądzę, aby te obawy dotyczyły postawionego pytania Obsługa przestrzeni jest problemem związanym z interfejsem użytkownika; Systemy uniksowe potrafią obsługiwać spacje w nazwach plików tak dobrze, jak Windows. Nielegalne znaki Windows są nadzbiorem znaków uniksowych. W nazwach plików Windows nie może być żadnych ukośników odwrotnych (oprócz separatorów katalogów, które zostaną przekonwertowane). Używanie cudzysłowów w przestrzeniach osadzonych stanowi problem na poziomie interfejsu użytkownika, a nie problem z obsługą plików. Kod konwersji jest najwyraźniej w Javie, więc powinien automatycznie obsługiwać konwersję UCS16-> UTF8.
Jules
-1

Każdy system operacyjny Microsoft, poczynając od MS-DOS, rozumiał na poziomie jądra zarówno ukośniki do przodu , jak i ukośniki odwrotne .

Dlatego w systemie Windows możesz swobodnie konwertować między nimi; oba mają równy status jako zarezerwowane separatory. W dowolnej prawidłowej ścieżce możesz zamienić ukośniki odwrotne ukośnikami i odwrotnie, bez zmiany jego znaczenia, jeśli chodzi o jądro.

We wczesnych wersjach DOS command.cominterpreter Microsoftu ustawiał konfigurowalne preferencje, które slash był używany do wyświetlania i analizowania ścieżek. To zostało ostatecznie usunięte.

Niektóre programy przestrzeni użytkownika w systemie Windows, takie jak och, powłoka systemu Windows ( explorer.exe), nie lubią ukośników. To po prostu tandetne programowanie w tych programach.

Kaz
źródło
1
Chociaż jest to prawda, nie sądzę, aby było pomocne w przypadku pytania PO, które (AIUI) obejmowało konwersję istniejących nazw ścieżek, które już zawierałyby w nich odwrotne ukośniki. Jest to bardzo przydatne do pisania kodu wieloplatformowe sobie sprawę, że można po prostu użyć ukośniki i ich pracy w większości kontekstów, ale w tym przypadku nie sądzę, że to pomaga.
Jules
@Jules OP przenosi pliki z systemu Windows. Ta odpowiedź wyjaśnia, że ​​nie ma żadnych odwrotnych ukośników. W ogóle nie znajdują się w systemie plików Windows. Wszystkie ścieżki można wyrazić za pomocą ukośników (i nawet Windows to rozumie).
Kaz