2009-05-14 39 views
46

Gần đây tôi đã phải chuyển đổi mã hóa webapp mà tôi đang làm việc từ ISO-xx thành utf8. Mọi thứ diễn ra trôi chảy, ngoại trừ các tệp thuộc tính. Tôi đã thêm -Dfile.encoding=UTF-8 vào eclipse.ini và các tệp thông thường hoạt động tốt. Tuy nhiên các thuộc tính cho thấy một số hành vi kỳ lạ.Thuộc tính Java Mã hóa UTF-8 trong Eclipse

Nếu tôi sao chép utf8 thuộc tính được mã hóa từ Notepad ++ và dán chúng vào Eclipse, chúng hiển thị và hoạt động tốt. Khi tôi mở lại tệp thuộc tính, tôi thấy một số ký tự Unicode thay vì các ký tự hợp lệ, như:

Zur\u00EF\u00BF\u00BDck instead of Zurück 

nhưng ứng dụng vẫn hoạt động tốt. Nếu tôi bắt đầu chỉnh sửa thuộc tính, hãy thêm một số ký tự đặc biệt và lưu, chúng hiển thị chính xác, tuy nhiên chúng không hoạt động và tất cả ký tự đặc biệt làm việc trước đó không hoạt động nữa.

Khi tôi so sánh phiên bản địa phương với CVS, tôi có thể thấy các ký tự đặc biệt chính xác trên tệp từ xa và sau khi cập nhật tôi bắt đầu lại: ứng dụng hoạt động, nhưng Eclipse hiển thị ký tự Unicode.

Tôi đã thử thay đổi mã hóa tệp bằng cách nhấp chuột phải vào mã hóa và chọn „Khác: UTF8” nhưng không hiệu quả. Nó cũng cho biết: “xác định từ nội dung: ISO-8859-1”

Tôi đang sử dụng Java 6 và Jboss phát triển dựa trên Eclipse 3.3

tôi có thể sống với nó bằng cách chỉnh sửa các thuộc tính trong Notepad ++ và dán chúng vào Eclipse, nhưng tôi sẽ biết ơn nếu ai đó có thể giúp tôi sửa lỗi này trong Eclipse.

Trả lời

51

Đừng lãng phí thời gian của bạn, bạn có thể sử dụng Resource Bundle plugin trong Eclipse

Basic Screen Shot

Old Sourceforge page

+3

Đây là một plugin cực kỳ hữu ích, cảm ơn bạn đã tip! Vì vậy, nó không có URL cài đặt, nhưng chỉ cần thả nó vào thư mục plugins thực hiện thủ thuật – chesterbr

+3

Điều này có sử dụng công cụ native2ascii không cho các ký tự không phải unicode trong nội bộ hoặc tôi nên tự thoát khỏi các ký hiệu unicode? –

+0

@ baybora.oren: Tôi đã mở rộng tệp .zip trong plugin thư mục eclipse, nhưng tôi không thấy bất kỳ thay đổi nào trong ide (tôi tắt máy và khởi động lại nhật thực). Bất kỳ gợi ý nào? – Sefran2

62

Tệp thuộc tính theo định nghĩa ISO-8859-1 - xem tài liệu cho lớp Properties.

Mùa xuân có thể thay thế có thể tải bằng mã hóa được chỉ định, sử dụng PropertiesFactoryBean.

EDIT: Như Laurence đã lưu ý trong các nhận xét, Java 1.6 đã giới thiệu quá tải cho loadstore mất Reader/Writer. Điều này có nghĩa là bạn có thể tạo trình đọc cho tệp bằng bất kỳ mã hóa nào bạn muốn và chuyển nó đến load. Rất tiếc, FileReadervẫn là không cho phép bạn chỉ định mã hóa trong hàm tạo (aargh), do đó bạn sẽ bị mắc kẹt với chuỗi FileInputStreamInputStreamReader cùng nhau. Tuy nhiên, nó sẽ hoạt động.

Ví dụ, để đọc một tập tin sử dụng UTF-8:

Properties properties = new Properties(); 
InputStream inputStream = new FileInputStream("path/to/file"); 
try { 
    Reader reader = new InputStreamReader(inputStream, "UTF-8"); 
    try { 
     properties.load(reader); 
    } finally { 
     reader.close(); 
    } 
} finally { 
    inputStream.close(); 
} 
+5

Trong Java 1.6, bạn có thể sử dụng các mã hóa khác bằng cách sử dụng các phương pháp sử dụng Reader/Writer thay cho InputStream/OutputStream. –

+0

Một giải pháp tổng quát hơn so với câu trả lời được chấp nhận, do đó tốt hơn :) –

12

Nó không phải là một vấn đề với Eclipse. Nếu bạn đang sử dụng lớp Properties để đọc và lưu trữ tệp thuộc tính, lớp sẽ thoát khỏi tất cả các ký tự đặc biệt.

From the class documentation:

Khi lưu tài sản cho một dòng hoặc tải chúng từ một dòng suối, nhân vật mã hóa theo tiêu chuẩn ISO 8859-1 được sử dụng. Đối với các ký tự không thể được biểu diễn trực tiếp trong mã hóa này, các lối thoát Unicode được sử dụng; tuy nhiên, chỉ có một ký tự 'u' được cho phép trong một chuỗi thoát. Công cụ native2ascii có thể được sử dụng để chuyển đổi các tệp thuộc tính đến và từ các mã hóa ký tự khác.

From the API, store() method:

nhân vật ít hơn \ u0020 và các nhân vật lớn hơn \ u007E được viết như \ uXXXX cho xxxx giá trị thập lục phân thích hợp.

+0

Tôi chỉ là skeet'd ... :( –

+3

NetBeans hiển thị độc đáo các tệp thuộc tính có \ uXXXX thoát và cho phép bạn chỉnh sửa chúng với các ký tự UTF được hiển thị đúng cách Theo tôi, đây là một vấn đề với Eclipse – ChrisB

+0

+1: lượng tử của sự an ủi vì đã bị lệch đi – rexford

4

Có quá nhiều điểm trong quá trình bạn mô tả nơi có thể xảy ra lỗi, vì vậy tôi sẽ không thử đoán xem bạn đang làm gì sai, nhưng tôi nghĩ tôi biết điều gì đang xảy ra dưới mui xe.

EF BF BD là dạng mã hóa UTF-8 là U+FFFD, ký tự thay thế chuẩn được chèn bởi bộ giải mã khi chúng gặp phải đầu vào không đúng định dạng. Có vẻ như văn bản của bạn đang được lưu dưới dạng ISO-8859-1, sau đó đọc như thể là UTF-8, sau đó được lưu dưới dạng UTF-8, sau đó được chuyển đổi sang định dạng Thuộc tính sử dụng native2ascii bằng cách sử dụng mã hóa mặc định nền tảng (ví dụ: windows- 1252).

ü    => 0xFC    // save as ISO-8859-1 
0xFC   => U+FFFD    // read as UTF-8 
U+FFFD   => 0xEF 0xBF 0xBD  // save as UTF-8 
0xEF 0xBF 0xBD => \u00EF\u00BF\u00BD // native2ascii

Tôi đề nghị bạn để riêng thuộc tính "file.encoding". Giống như "file.separator" và "line.separator", nó không hữu ích như bạn mong đợi. Thay vào đó, hãy tập thói quen luôn chỉ định mã hóa khi đọc và ghi tệp văn bản.

1

Điều này dường như chỉ hoạt động đối với một số ký tự ... bao gồm các ký tự đặc biệt cho tiếng Đức, tiếng Bồ Đào Nha, tiếng Pháp. Tuy nhiên, tôi gặp rắc rối với các nhân vật tiếng Nga, tiếng Hindi và tiếng Quan Thoại. Đây không phải là chuyển đổi sang định dạng Properties 'native2ascii', thay vào đó được lưu với ?? ?? ??
Cách duy nhất để ứng dụng của tôi hiển thị đúng các ký tự này là đặt chúng vào tệp thuộc tính được dịch sang định dạng UTF-8 - như \ u0915 thay vì क hoặc \ u044F thay vì я. Bạn có lời khuyên nào không?

+0

Bạn có thể sử dụng org.springframework.context.support.ReloadableResourceBundleMessageSource của Spring hỗ trợ UTF- Chúng tôi sử dụng Spring để quản lý các bản dịch bằng tiếng Anh, tiếng Đức, tiếng Pháp và tiếng Trung trong các ứng dụng web dựa trên mùa xuân-MVC – rexford

9
Properties props = new Properties(); 
URL resource = getClass().getClassLoader().getResource("data.properties");   
props.load(new InputStreamReader(resource.openStream(), "UTF8")); 

trình như một say mê

:-)

+0

Thật không may props.load, trong 1.6, yêu cầu InputStream và đặc biệt cho biết nó mong đợi trường học cũ ISO-8859-1 –

4
Properties props = new Properties(); 
URL resource = getClass().getClassLoader().getResource("data.properties");   
props.load(new InputStreamReader(resource.openStream(), "UTF8")); 

hoạt động tốt trong java 1.6. Làm thế nào tôi có thể làm điều này trong 1,5, Kể từ khi lớp Properties không có một phương pháp để phân tích cú pháp InputStreamReader.

-1

Nếu các thuộc tính là dành cho XML hay HTML, đó là an toàn nhất để sử dụng các đối tượng XML. Họ xấu hơn để đọc, nhưng nó có nghĩa là các tập tin thuộc tính có thể được coi là ASCII thẳng, vì vậy không có gì sẽ bị xáo trộn.

Lưu ý rằng HTML có các thực thể XML không, vì vậy tôi giữ nó an toàn bằng cách sử dụng XML thẳng: http://www.w3.org/TR/html4/sgml/entities.html

1

tôi khuyên bạn nên sử dụng Attesoro (http://attesoro.org/). Là đơn giản và dễ sử dụng. Và được làm bằng java.

4

Có cách dễ dàng hơn nhiều:

props.load(new InputStreamReader(new FileInputStream("properties_file"), "UTF8")); 
1

Bạn có thể xác định UTF-8 .properties file để lưu trữ các bản dịch của bạn và sử dụng ResourceBundle, để có được giá trị. Để tránh sự cố, bạn có thể thay đổi mã hóa:

String value = RESOURCE_BUNDLE.getString(key); 
return new String(value.getBytes("ISO-8859-1"), "UTF-8"); 
Các vấn đề liên quan