nem ascii fájlnevek

Windows 2000-en csinálok egy fájlt így:

echo "ötszépszűzlány" >"ötszépszűzlány"

batchből, garantáltan ISO-8859-2 kódolással. Létrejön tehát egy ilyen nevű fájl ugyanilyen tartalommal. A dir parancs szépen visszaadja a fájl Latin-2 kódolású nevét.

Ha azonban C-ből listázom a fájlnevet (a FindFirstFile, FindNextFile API-val), akkor szemetet kapok. Pl. az 'é' helyén 'T' van. A FindFirstFile doksijában nincs szó nonascii karakterekről.

Tudja-e valaki, hogyan lehet hozzájutni C-ből a nem ascii fájlnevekhez?

Megj: Van megoldás, hiszen a Windows konzol dir parancsa is kikaparja valahonnan a valódi fájlnevet. A samba kliensben is jól látszik a fájlnév. De a cygwin-es dir rossz. A python os.listdir() szintén rossz. Egyelőre nem találtam olyan nyílt forrású programot, ami ezt jól csinálná, hogy koppintani lehetne belőle.

Hozzászólások

rosszul tudom, hogy szemben a FAT-tal az NTFS alapból UTF fájlneveket csinál?

(mellesleg 5 szép lánnyal még megértem, de 5 szép szűzlánnyal mi a fenét csinálsz??)

Szervác Attila - http://321.hu/sas

A windows alapból unicode, minden függvénynek van ascii és unicode verziója (valójában az ascii csak konvertál és a unicode-ost hívja). Tehát van egy FindFirstFileA és egy FindFirstFileW, és a FindFirstFile egy makro, ami a UNICODE define-tól függően hívja az ascii vagy a unicode verziót. Tehát vagy tedd unicode-osra a projectedet, vagy direktbe hivogasd a FindFirstFileW stb. függvényeket.
Remélem érthető amit irtam, a winbase.h-ban megnézheted.

Köszönöm, ez értékes infó volt. A probléma még nem oldódott meg, mert egyelőre nem tudtam kitalálni, hogy milyen kódolásban adja a neveket a FindNextFileW.

A Latin-1-2-vel létrehozott fájlnevek 16 bites unicode-ban jönnek.

Az UTF-8-ban létrehozott fájlnevek valami változó hosszúságú kódolással jönnek (nem UTF-8), amiben a 128-nál kisebb karakterek 16 biten vannak ábrázolva, a 128-nál nagyobbak 32 biten.

Nem értem hogyan különbözteti meg a két esetet.

Mit lehet tudni arról, hogy a kódolás hogyan tér el Windows verziók és filérendszerek (NTFS/FAT) között?

--
CCC3

Megj: Ez nem egy iskolai vagy munkahelyi feladat, hanem az előbbi linkben leírt, Linuxon fejlesztett, LGPL-es izének a windowsos portjához kell.

Szerk: Azt továbbra sem tudom, milyen kódolást használ belül a Windows, de a WideCharToMultiByte (FindNextFileW után) visszaadja az eredeti bytesorozatot, ennyi most elég nekem.

Az megvan, hogy a FindFirstFile/FindNextFile-lal visszakapjam a filék eredeti nevét (megoldás: a FindNextFileW wide char változatot kell használni, plusz a WideCharToMultiByte karakterkonverziót). Ezzel azonban koránt sincs vége a szenvedésnek, ui. a spéci nevű filéket a POSIX API-val (mint open, stat) _sem_ lehet megtalálni.

Gondolom ez az oka, hogy a Cygwin és a Python sem kezeli Windowson a nonascii filéneveket. Nem ezek szintjén kellene javítani, hanem a gcc/MinGW POSIX interfészén. Erre viszont nincs kilátás. Ezért gondolkozom még, hogy lemondjak-e Windowson a nonascii filékről, vagy kitaláljak valamit.

--
CCC3

Próbálkozz a _wfopen _wstat és hasonló függvényekkel (a szokott c függvény _w -vel kiegészítve), ha van egyáltalán ilyesmi a mingw c libraryben. Elvben ezek kezelik a wchar_t tipusú (azaz unicode) filerendszert.
Visual C-ben van egy tchar.h header, ha van ilyesmid, érdemes azt használni, mert így tudsz ansi-r és unicode-ra is fordítani.

Nem így néz ki a dolog. Olyasmit csinálok, mint a Python (CCC), azt is elsősorban Linuxon. Először Linuxon akarok működni, a Windows kedvéért nem lehet mindent szétdúlni. A CCC programok tehát a Linux/UNIX logikát követik. A filéneveket az alkalmazások 32 bites unicode (wchar_t) stringként vagy bytesorozatként (char) tárolják. Az első esetben (wchar_t string) UTF-8 kódolásban kerül lejjebb a filénév a POSIX API-hoz. A második esetben (char string) olyan a kódolás, ahogy az alkalmazás létrehozta a char stringet. Ez Linuxon prímán megy, mert az UTF-8 kódolás elég jó ötlet volt. A fájlrendszer null terminated bytesorozatként kapja és tárolja a neveket.

Ha egyáltalán tovább vesződnék a windowsos porttal, akkor ezt csinálnám:

1) Megkeresném azokat a helyeket, ahol név alapján keres filét a CCC alapkönyvtár.

2) Ezeken a helyeken a MultiByteToWideChar plusz CreateFileW-vel megnyitnám a filét.

3) A hordozható HANDLE->filedescriptor függvénnyel (nem emlékszem most hogy hívják) megnyitnám a fileleírót.

4) A fájlleíróval továbbra is lehetne a POSIX API-t használni, ahogy eddig is volt.

Arra gondoltam, hogy a gcc/MingW könyvtárában levő POSIX implementációnak is ilyennek kellene lennie. Nem ilyen, de nem is működik jól a windowsos Python és a Cygwin. Nem jártam nagyon aprólékosan utána, csak éppen kipróbáltam: a cygwines dir parancs és a Pythonban levő os.dirlist is rossz (ebből a szempontból). A MinGW könyvtárat én nem fogom átírni, viszont kerülgetni sincs kedvem a hibákat, úgyhogy egyelőre mással foglalkozom.

A segítséget köszönöm.

--
CCC3