CopyFile - problem

dział ogólny

CopyFile - problem

Nowy postprzez mckri » czwartek, 10 lutego 2011, 10:16

Witam.
Wykorzystuję do kopiowania plików funkcję CopyFile. Natknąłem się na problem podczas kopiowania między lokalizacjami o długich nazwach.
Gdy lokalizacja docelowa ma więcej niż 256 znaków, wtedy GetLastError() zwraca "System nie może odnaleźć określonej ścieżki". Podobny problem wystepuje równiez dla polecenia xcopy.
Czy takie ograniczenie na długość sciezki można usunąć, lub zwiekszyć jej zakres? Czy istnieje inna funkcja równie szybka, która można wykorzystać do kopiowania? Wiem że można wykorzystać TSHFileOpStruct, ale chyba jest wolniejsza niż CopyFile.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: CopyFile - problem

Nowy postprzez Cyfrowy Baron » czwartek, 10 lutego 2011, 11:05

Musisz zmienić ścieżkę długą na ścieżkę krótką i do kopiowania używać krótkiej:

KOD cpp:     UKRYJ  
#include <stdio.h>

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  TCHAR longOldPath[] = L"c:\\stara lokalizacja\\plik.roz";
  TCHAR shortOldPath[MAX_PATH];

  long length = GetShortPathName(longOldPath, shortOldPath, MAX_PATH);
  if(length == 0)
  {
   ShowMessage("Wskazana stara lokalizacja nie istnieje");
   return;
  }

  TCHAR longNewPath[] = L"c:\\nowa lokalizacja";
  TCHAR shortNewPath[MAX_PATH];

  length = GetShortPathName(longNewPath, shortNewPath, MAX_PATH);

  if(length == 0)
  {
   ShowMessage("Wskazana nowa lokalizacja nie istnieje");
   return;
  }

  wcscat(shortNewPath, L"\\plik.roz"); /* wcscat dla wchart_t dla char - strcat */

  CopyFile(shortOldPath, shortNewPath, FALSE);
}


To działa nie tylko z długimi ścieżkami, lecz z każdymi. Długość ścieżki po konwersji nie może być większa niż 260. Ścieżka przekazana funkcji GetShortPathName musi istnieć.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: CopyFile - problem

Nowy postprzez mckri » czwartek, 10 lutego 2011, 11:13

Dzięki. Myslałem o tym. No jest to jakies rozwiązanie.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: CopyFile - problem

Nowy postprzez Cyfrowy Baron » czwartek, 10 lutego 2011, 11:30

No jest to jakies rozwiązanie.


To jedyne rozwiązanie, gdyż ścieżka dostępu do pliku nie może być dłuższa niż 255 znaków i w Windows 7 też się to nie zmieniło. Wynika to z faktu, że długość ścieżki nie może być większa niż 32-bity. System Windows obsługuje oczywiście zagłębienie katalogów dające ścieżkę większą niż 255 znaków dokonując prawdopodobnie niejawnej konwersji na krótkie nazwy katalogów i plików.
Na stronie http://support.microsoft.com/kb/320081/pl możemy przeczytać:


Przyczyna 4: Pliki znajdują się w ścieżkach na poziomach niższych niż liczba znaków MAX_PATH
Nie zawsze można otworzyć, edytować lub usunąć plik, jeżeli występują problemy ze ścieżką pliku.
Rozwiązanie 1: Użycie automatycznie generowanej nazwy w formacie 8.3 w celu uzyskania dostępu do pliku
W celu rozwiązania tego problemu konieczne może być użycie automatycznie generowanej nazwy w formacie 8.3, aby uzyskać dostęp do pliku. To rozwiązanie może był najłatwiejsze, jeżeli ścieżka znajduje się na niskim poziomie w strukturze, ponieważ nazwy folderów są zbyt długie. Jeżeli ścieżka w formacie 8.3 jest zbyt długa lub obsługa nazw w formacie 8.3 została wyłączona dla danego woluminu, należy przejść do sekcji Rozwiązanie 2. Aby uzyskać dodatkowe informacje dotyczące wyłączania obsługi nazwy w formacie 8.3 dla woluminów NTFS, kliknij następujący numer artykułu w celu wyświetlenia tego artykułu z bazy wiedzy Microsoft Knowledge Base:
121007 Jak wyłączyć tworzenie nazw w formacie 8.3 na partycjach systemu NTFS


Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: CopyFile - problem

Nowy postprzez mckri » czwartek, 10 lutego 2011, 13:29

Jest jeszcze jedna funkcja, łatwiejsza w uzyciu: ExtractShortPathName(UnicodeString FileName).
Obie mają jednak duży mankament. Wymagają, aby ścieżka istniała. Mam tu na mysli lokalizację docelową, do której kopiuję pliki.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: CopyFile - problem

Nowy postprzez Cyfrowy Baron » czwartek, 10 lutego 2011, 13:47

Pisząc, że nie ma innego rozwiązania, chodziło mi o to, że nie ma innego wyjścia niż przekształcenie nazwy ścieżki z długiej na krótką, a wybór funkcji to sprawa drugorzędna.

Obie mają jednak duży mankament. Wymagają, aby ścieżka istniała.


A cóż to za mankament. Jeżeli ścieżka nie istnieje, to co Tobie z niej przyjdzie. W jakiej sytuacji jest Tobie potrzebna nieistniejąca ścieżka?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: CopyFile - problem

Nowy postprzez mckri » czwartek, 10 lutego 2011, 13:58

A cóż to za mankament. Jeżeli ścieżka nie istnieje, to co Tobie z niej przyjdzie. W jakiej sytuacji jest Tobie potrzebna nieistniejąca ścieżka?

Wykonuję operacje kopiowania. Kopiowanie ma to do siebie, ze w lokalizacji docelowej plik może jeszcze nie istnieć.
Ale już widzę, że ten problem będzie mozna rozwiązac.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: CopyFile - problem

Nowy postprzez Cyfrowy Baron » czwartek, 10 lutego 2011, 14:15

Przecież podany przeze mnie kod uwzględnia to rozwiązanie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: CopyFile - problem

Nowy postprzez mckri » czwartek, 10 lutego 2011, 21:33

Przecież podany przeze mnie kod uwzględnia to rozwiązanie.

Nie. Chyba że testowałeś swój kod na takich własnie ścieżkach, które istniały u Ciebie istniały na dysku.
Miałem na mysli fakt, że funkcja GetShortPathName wymaga, aby podana ścieżka istniała fizycznie. Dla mnie to bez sensu. bo skoro chce sie skopiowac plik do nowej lokalizacji (która jeszcze nie istnieje), to w zasadzie nie mogę przedstawić ścieżki w postaci skróconej.
Informacja z helpa:
ExtractShortPathName converts the given filename to the short form by calling the GetShortPathName Windows function. It returns an empty AnsiString if the file or directory specified does not exist.
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
Podziękował : 10
Otrzymał podziękowań: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    Windows VistaOpera

Re: CopyFile - problem

Nowy postprzez Cyfrowy Baron » czwartek, 10 lutego 2011, 21:41

Dla mnie to bez sensu. bo skoro chce sie skopiowac plik do nowej lokalizacji (która jeszcze nie istnieje), to w zasadzie nie mogę przedstawić ścieżki w postaci skróconej.


Przecież przed skopiowaniem pliku i tak musisz utworzyć katalogi, więc najpierw tworzysz katalogi (ForceDirectories), a potem skracasz ścieżki i kopiujesz plik. Funkcja musi sprawdzać, czy w podanej lokalizacji istnieje już katalog, gdyż mogą występować katalogi o niemal identycznych nazwach, którym przypisywane są liczby od 1, gdzie liczba oznacza katalog według kolejności alfabetycznej.

Nie. Chyba że testowałeś swój kod na takich własnie ścieżkach, które istniały u Ciebie istniały na dysku.


Mój kod uwzględnia tylko istniejącą lokalizację, ale... zresztą przeanalizuj go a zrozumiesz.

Zadanie z kopiowaniem do nie istniejącej lokalizacji nie powinno nastręczać problemów, wszak zawsze przed skopiowaniem musisz utworzyć katalogi, gdyż funkcja kopiująca ich nie tworzy.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox


Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 4 gości