2009-10-09 21 views
12

Dosyalarla çeşitli IO işlemleri yapan kodlarla uğraşıyorum ve uluslararası dosya adlarıyla başa çıkabilmeyi istiyorum. Java 1.5 ile bir Mac üzerinde çalışıyorum ve bir dosya adı surrogates gerektiren Unicode karakterler içeriyorsa, JVM dosyayı bulamıyor gibi görünmüyor. Örneğin, benim test dosyasıdır: Java karakterleri \u8349\uD85B\uDFF6\u9DD7\u5916.gifJava, Dosya Adında Unicode Değerleri ile Dosya Açamaz mı?

Bu dosya bir dosya oluşturursanız ben FileNotFound istisna olsun çünkü, bunu açamıyor içine bozuluyor

"草鷗外.gif". Hatta başarısız olur dosyasını içeren klasöre bu kullanarak: Aslında uğraşıyorum kod çoğu

File[] files = folder.listFiles(); 
for (File file : files) { 
    if (!file.exists()) { 
     System.out.println("Failed to find File"); //Fails on the surrogate filename 
    } 
} 

biçimdedir:

FileInputStream instream = new FileInputStream(new File("草鷗外.gif")); 
// operations follow 

ben bu sorunu ele alabilir bazı yolu var mı, dosya isimlerinden kaçmak ya da dosyaları farklı açmak mı?

+0

Ortamınızdaki Charset.defaultCharset() değeri nedir? –

+2

(Ne yazık ki, StackOverflow ayrıca vekillerle ilgili bir soruna da sahip ve sorudan U + 26FF6 ideografını çıkardı) – bobince

+0

Hangi System.getProperty ("file.encoding") işlevinin ne getirdiğini sağlayabilir misiniz? Kodlamayı değiştirmeyi deneyin java -dfile.encoding = ENCODING_GOES_HERE ise sistem yerel ayarlarınızı değiştirmez. Bu da işe yaramıyorsa, bir uzmanı çözmek için bekleyeceğiz. – JCasso

cevap

4

Ortamınızın varsayılan yerel ayarı, dosyayı açamadığınız karakterleri içermiyorsa.

Bkz: File.exists() fails with unicode characters in name

Düzenleme: Tamam .. Ne gerek sistem yerel değiştirmektir. Kullandığınız işletim sistemi.

Düzenleme:

Bkz: How can I open files containing accents in Java?

Bkz: JFileChooser on Mac cannot see files named by Chinese chars?

+0

'dur. Sistem yerel ayarını değiştirmeden bunu yapmak mümkün değil mi? Yapmakta olduğum programın herhangi bir yerel ayarda çalışması gerekiyor ve bu karakterleri girip bu dosyalarla ABD/İngilizce yerel ayarlarında bile ilgilenebilmem gerekiyor. – Bear

+0

Kötü bir çözüm - uygulama bilgisayarımda oturmayan kullanıcılar için çalıştırıldığı için. Ve farklı yerel ayarlara sahipler ve bunu yapmak için en üst düzey yönetici yok. –

+0

AFAIK başka bir çözüm yok. Bu sınırlama Sun/Oracle Java ile birlikte geliyor. Kullanıcılarınıza kaydetme iletişim kutusu görüntülüyorsanız, JFileChooser'ı deneyebilirsiniz. – JCasso

7

yerine doğru UTF-8'in CESU-8 kullanıyor Java veya Mac biri şüpheli. Java, çeşitli dahili amaçlar için “değiştirilmiş UTF-8” (CESU-8'in küçük bir değişkeni) kullanır, ancak bunu bir dosya sistemi/defaultCharset olarak kullanabileceğinin farkında değildim. Ne yazık ki burada test etmek için ne Mac ne de Java var.

“Değiştirilmiş”, “kötü bir şekilde etiketlenmiş” demenin değiştirilmiş bir yoludur. Bunun yerine gibi karakterleri tamamlayıcı (non-BMP) için dört bayt UTF-8 dizisini çıktısı ve

\xF0\xA6\xBF\xB6 

bu suretler her biri için bir UTF-8 kodlanmış dizisini verir # x26FF6 ;::

\xED\xA1\x9B\xED\xBF\xB6 

Bu geçerli bir UTF-8 dizisi değil, ancak bir çok kod çözücü buna izin verecek. Sorun şu ki, gerçek bir UTF-8 kodlayıcısından bunu gerçekleştirirseniz, yukarıdaki dört baytlık bir farklı dizginiz vardır. Dosyaya bu isim ve bom ile erişmeyi deneyin! başarısız.

Böylece ilk Sadece böyle Python 2.x olarak dosya adları için bayt kullanan bir platformu kullanarak, dosya adları aslında mevcut dosya sistemi altında kayıtlı olduğunu kontrol edelim:

benim dosya sistemi üzerinde
$ python 
Python 2.x.something (blah blah) 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import os 
>>> os.listdir('.') 

(Linux, ext4'ün UTF -8), dosya adı “草 & # x26FF6; 鷗 外.gif ”, istediğiniz gibi olan

['\xe8\x8d\x89\xf0\xa6\xbf\xb6\xe9\xb7\x97\xe5\xa4\x96.gif'] 

. Eğer aldığın buysa, muhtemelen Java yanlış yapıyordur. Daha uzun altı bayt karakter sürümünü alırsanız: muhtemelen OS X yanlış yapıyor

['\xe8\x8d\x89\xed\xa1\x9b\xed\xbf\xb6\xe9\xb7\x97\xe5\xa4\x96.gif'] 

bu kadar ... Hep böyle mi dosya adlarını depolar? (Ya dosyalar başka bir yerde başlangıçta geldi?) Eğer 'uygun' sürümü ?: Bu Mac JVM ile ilgili bir sorun olduğu ortaya çıktı

os.rename('\xe8\x8d\x89\xed\xa1\x9b\xed\xbf\xb6\xe9\xb7\x97\xe5\xa4\x96.gif', '\xe8\x8d\x89\xf0\xa6\xbf\xb6\xe9\xb7\x97\xe5\xa4\x96.gif') 
+2

Gerçekten de bir özellik gibi bir hata değil (genellikle kafa karıştırıcı olsa bile.) – finnw

+0

Python komutlarının sonucu, önce listelediğiniz doğru dosya adıydı, bu yüzden Java'nın iyi oynamaması gerekir. – Bear

+0

Oh, bu talihsiz bir şey. Kırık-CESU-8 durumunu tespit etmiş olsanız bile, etrafta çalışmak ve byte-yönelimli bir dosya adı arayüzü elde etmek için herhangi bir yol düşünemiyorum. :-(Vekilleri, Sun düzelteceği zamana kadar açıkça izin vermeniz gerekebilir. – bobince

3

dosyayı yeniden adlandırmak ne olur (1.5 ve 1.6 üzerinde test). Ek karakterler/vekil çiftleri içeren dosya isimlerine, Java File sınıfı ile erişilemez. Karbonlu JNI kütüphanesi yazarak, Mac'in projenin (ick) Mac versiyonunu çağırdım. Bahsedilen CESU-8 meselesi bobince olduğundan şüpheleniyorum, çünkü JNI çağrısı UTF-8 karakterleri CESU-8 dizesi döndürdü. Gerçekten etrafta dolanabileceğin bir şey gibi görünmüyor.

0

Eski skool java File API'sinde bir hata var, belki sadece bir macda? Her neyse, yeni java.nio api çok daha iyi çalışıyor. Java.io.File ve ilgili sınıfları kullanarak yüklenemeyen unicode karakterler ve içerik içeren birkaç dosyam var. Tüm kodumu kullantıktan sonra java.nio.Path EVERYTHING çalışmaya başladı. Ve org.apache.commons.io.FileUtils (aynı sorunu olan), java.nio.Files ...

ile değiştirildi ... ve uygun bir karakter kümesini kullanarak dosyanın içeriğini okuduğunuzdan ve yazdığınızdan emin olun. Örneğin: Files.readAllLines (myPath, StandardCharsets.UTF_8)