- 471 megtekintés
 
Hozzászólások
Kell, hogy javat használj? iconv / recode / uconv (az ICU-féle)? (Igen, ezek *X-en elterjedtebbek, mint Win-en, de ötletet kértél.)
- A hozzászóláshoz be kell jelentkezni
 
Igen, kell. Illetve megírhatnám másban is, de ebben volt kényelmes. Windows-on futó kliens hívja.
- A hozzászóláshoz be kell jelentkezni
 
A forrást nem teszed fel? Ha már 5 sor?
> NoSuchFileException: K?N_202410_2411111223.xml
Szerintem a parancssorban megkapott paramétert más encoding szerint értelmezi, mint amiben valójában jön. Például azt hiszi, hogy a paraméternek is UFT-8-ban kell jönni, de a Windows valami másban küldi. A paraméter beolvasása Java Stringbe a programod indítása előtt megtörténik, tehát ezzel nem tud a programod semmit se csinálni, ennek jónak kell lenni eleve, különben nem fogja tudni betölteni a fájlt, az a hiba lesz, amit írtál.
Ha biztosra akarsz menni, akkor a bináris ábrázolását a bemeneti paraméternek visszaírod (azért nem a stringet, mert azt meg a terminál is elronthatja, ha félre van konfigolva) a program futása elején, és akkor kiderül, hogy tényleg ez-e a probléma. Belül a Java szerintem már a Windowsnak az U16 API-ját használja, ha egyszer jól van a fájlnév a JVM-ben, akkor már meg fogja tudni nyitni. De az ördög nem alszik...
A megoldást persze nem tudom, nem találkoztam még ilyennel, hogy a parancssori paramétert ne jól olvasta volna ki a Java. A saját programjainkban mindig explicit megadjuk, hogy melyik fájlnak mi az enkódolása, és sose építünk a konfigurált beállításokra. A paraméterek meg eddig mindig jól jöttek, bár tény, hogy többnyire nem is használunk ékezetes fájlneveket, lehet, hogy ki se derült volna, ha ilyen van.
- A hozzászóláshoz be kell jelentkezni
 
Jogos. Íme a kód.
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class utf8 {
    public static void main(String[] args) throws IOException {       
        Path p = Paths.get(args[0]);
        ByteBuffer bb = ByteBuffer.wrap(Files.readAllBytes(p));
        CharBuffer cb = Charset.defaultCharset().decode(bb);
        BufferedWriter output = Files.newBufferedWriter(p, StandardCharsets.UTF_8);
        output.write(cb.array());
        output.close();
    }
}
A probléma csak az ékezetes fájlnevekkel van természetesen. Bennem van még a zsigeri érzés, hogy kerüld az ékezeteket, de 2024-ben ez már ne legyen probléma..
- A hozzászóláshoz be kell jelentkezni
 
Nem lehet a Charset.defaultEncoding helyett átadni explicite, hogy milyen charset legyen használva? A sun.jnu.encoding azt írja felül, hogy a parancssor milyen encodinggal jön be a processzbe. Lásd: https://happygiraffe.net/2009/09/24/java-platform-encoding/ De lehet, hogy ez nem standard, és ezért megváltoztathatják sima verziók között is a működését.
A Windows ugyanaz a két esetben? Nem a Windows ad át mást? Amit debuggolnék, hogy a Javában kiiratnám binárisan (A String char-jait számérték szerint) az argumentum értékét. Meg csinálnék egy C programot, ami szintén kiírja az argumentumait binárisan. Hogy mégis milyen kódolásban adja át a Windows azt a paramétert?
- A hozzászóláshoz be kell jelentkezni
 
A Windows ugyanaz, ugyanaz a gép is. Karakterenként végigmenve a kapott argv[0]-án eltér a kettő. Tehát a -Dsun.jnu.encoding=utf8 elrontja ebben az esetben a kódolást. (Enélkül a 431 illetve a 411 előtti verziók működnek).
Még nem adtam fel, de lehet, hogy megírom c-ben.
 
- A hozzászóláshoz be kell jelentkezni
 
Szerintem az a verzió a hibás, aminél meg kell adni a plusz paramétert, mert pont az a lényeg, hogy az argumentum átadásnak jól kell működni magától. Mivel a Java API-n String típusú a bemeneti paraméter, amit 16 bites UTF-re alakít belül (logikailag legalábbis), ezért sajnos a bináris eredetihez nem tudsz hozzáférni. El tudom képzelni, hogy a terminálban az ENV változók rosszak, és emiatt téved el a JRE, hogy mégis milyen encoding szerint értelmezze a bemenetet. A JRE8 open source, meg lehet nézni, hogy pontosan mit is csinál a bemenettel.
Alterntív megoldás eszképelni a bemenetet még mielőtt átadnád a programodnak, átnevezni a fájlt (ha már úgyis szkript dolgozik), vagy egy fájlba írni a bemeneti paramétereket ismert enkódolással. Esetleg JVM-et tenni a programka mellé. Sajnos ez mind jelentős bonyolítás.
- A hozzászóláshoz be kell jelentkezni
 
Messze a legegyszerűbb az lenne, hogy a szkriptet egészítsük ki egy fájlnévékezettelenítő "move Főkábel.txt fokabel.txt" (majd vissza Fókabél.txt-re :-) ?) lépéssel, és a probléma ténylegesen elhárult. Mivel elhangzott, hogy fix nevet kap.
Persze ez kikerülése a problémának, a valódi megoldás megtalálni azokat a környezeti sajátosságokat amik figyelembevételével az ékezetes args tömb korrekten kezelhető.
- A hozzászóláshoz be kell jelentkezni
 
Én is arra jutottam, h a 411 és a 421 a hibás. Mivel alapból 852-es kódlappal készül a fájl ezért fel kellene, hogy ismerje külön paraméter nélkül is.
Mindenképp szívás. A hívó programokhoz is hozzá kell nyúlni biztosan. Meg tesztelni, meg deploy-olni az ügyfelekhez ahol többféle java verzió lehetséges természetesen.
Ez amúgy olyan marginális terület, hogy nem tudok több erőforrást áldozni arra, hogy random verzióváltásoknál még ezt is vizsgáljam. Max. annyit teszek, hogy lekezelem a kivételt és dobok egy üzenetet a usernek, hogy hiba van és nem készült el a fájlt konverzió.
- A hozzászóláshoz be kell jelentkezni
 
> Még nem adtam fel, de lehet, hogy megírom c-ben.
Újfent tudnám említeni: iconv / recode / uconv. Ezeket már megírták és Windows alatt is futnak.
- A hozzászóláshoz be kell jelentkezni
 
Azért ezt érdekesnek találtam amikor a két nevet összehasonlítottam:
1.
KÖN_202410_2411111223.xml
2.
K?N_202410_2411111223.xml
Úgy értem, hogyan változott az "Ö" betű "?" karakterre...
Még nincs aláírásom.
- A hozzászóláshoz be kell jelentkezni
 
Az ? karakter az Ö betű lenne, ha értelmezni tudná a jvm, hogy milyen encoding-ról van szó. Így valóban teljesül és jogos a NoSuchFileException, de nem értem, hogy két patchset-el arrébb miért nem működik ugyanaz. (Három külön gépen tesztelve következetesen ez a hiba.)
- A hozzászóláshoz be kell jelentkezni
 
Ne használj ékezetes fájlneveket, a hívó program is lehet a hunyó ill ntfs-en utf-16 a fájlnév kódolás. :-p
- A hozzászóláshoz be kell jelentkezni
 
Ez jelen pillantban nem megoldás. A hívó program független a jre verzió változásától és ugyazt a fájlt készíti el A vagy B esetben is.
- A hozzászóláshoz be kell jelentkezni
 
Szerintem első lépésként az argumentumokat kellene UTF-8-ba (*) konvertálni, és a kovertált sztringeket átadni a további feldolgozásra.
(*) vagy amit a java belül használ
- A hozzászóláshoz be kell jelentkezni
 
Köszönöm, ez jó lehet. Futok egy kört vele.
- A hozzászóláshoz be kell jelentkezni
 
Szia!
Csak egy ötlet, de lehet, hogy a Compact Strings feature kavar be, próbáld már ki a jvm-et +XX:-CompactStrings paraméterrel indítani a problémás Java verziókon.
Esetleg még debuggerrel meg lehetne nézni, hogy a processz milyen paramétert kapott, a main-ben hogy néz ki, ha lekéred külön az argumentumokat mit mutatnak, valamint, hogy ezek a stringek internal hogy néznek ki.
szerk: egyébként by default UTF16-ban tárolja a stringet a java internal, kivéve ha ez a feature úgy ítéli meg, hogy Latin-1 karakterek vannak benne, mert akkor már csak 1 bájton.
- A hozzászóláshoz be kell jelentkezni
 
Unrecognized VM option 'CompactStrings'
Lehet, hogy az 1.8-ban nincs még ilyen ?
- A hozzászóláshoz be kell jelentkezni
 
Szia!
Jól értem az a probléma, hogy amit átadsz paraméterként annak a kódolását nem úgy értelmezi, ahogy szeretnéd?
A parancssor encodeolását érdemes ellenőrizni: chcp
- A hozzászóláshoz be kell jelentkezni
 
Igen, ez a probléma. A chcp 852-es kódlapot mutat.
- A hozzászóláshoz be kell jelentkezni
 
Én azt csinálnám, hogy egy bat fájlba beletenném a futtatást és előtte átállítanám a kódlapot. Azért érdemes beletenni egy bat fájlba, mert ha így az egyes kimeneteket is ki tudod irányítani akár külön fájlba is. Például, ha a programban exception esetén az error -ra írsz (pl System.err.println("valami hiba")) és sikeres futás esetén az out -ra (pl System.out.println("valami sikeres")), akkor ezt a bat fájlban a futtatáskor a megfelelő fájlokba vagy képernyőre tudod irányítani.
De persze, lehet máshogy is. Ahogy neked "olcsóbb" a megoldás.
Ha a kódba is kell segítség, keress nyugodtan.
- A hozzászóláshoz be kell jelentkezni
 
Köszönöm. Amúgy a .bat-nak a leírtakon kívül még az is előnye, hogy könnyen át lehet paraméterezni a dolgokat, ha esetleg az adott ügyfélnél valami nem úgy van. Bár az ügyfélspecifikus megoldásokat irtom tűzzel-vassal ahol csak lehet, néha jól jön, ha gyorsan kell megoldani valamit.
- A hozzászóláshoz be kell jelentkezni
 
Szívesen!
ui: JVM indítására bevett szokás például a bat fájl. Pontosan azért amit írsz: sok paraméter megadható.
- A hozzászóláshoz be kell jelentkezni