2010-06-10 58 views
10

tôi có tệp có một số ký tự không phải utf8 (như "ISO-8859-1") và vì vậy tôi muốn chuyển đổi tệp đó (hoặc đọc) thành mã hóa UTF8, Tôi phải làm việc đó như thế nào?java: cách chuyển đổi tệp thành utf8

Mã nó là như thế này:

File file = new File("some_file_with_non_utf8_characters.txt"); 

/* some code to convert the file to an utf8 file */ 

... 

chỉnh sửa: Đặt một ví dụ mã hóa

+0

Không phải UTF8? Bạn muốn thu hẹp xuống một chút? Thật dễ dàng khi bạn biết mã hóa đầu vào, và về cơ bản là không thể nếu bạn không. –

+0

một số cân nhắc, các tập tin là BIG (như 1GB) vì vậy tôi không thể đặt chúng trong một đối tượng String ... –

+0

mã hóa tệp của bạn là gì? Nếu bạn đang sử dụng Linux hoặc OS X (và các Un * x khác), bạn có thể chỉ cần gõ: * file some_file * và nó sẽ cho bạn biết mã hóa. Btw, nếu bạn đang ở trên Un * x (ít nhất là cả Linux và OS X), bạn nên có dòng lệnh * iconv *. * "man iconv" * cho biết: * "Chuyển đổi mã hóa các tệp đã cho từ mã hóa này sang mã hóa khác" *, được cho là sẽ thực hiện công việc tốt hơn trên tệp 1GB so với sử dụng Java tự viết. Lưu ý rằng mã hóa UTF-8 có thể đại diện cho mỗi điểm mã Unicode đơn, do đó nói rằng tệp * "có một số ký tự không phải là utf8" * âm thanh đáng ngờ ... – NoozNooz42

Trả lời

8
String charset = "ISO-8859-1"; // or what corresponds 
    BufferedReader in = new BufferedReader( 
     new InputStreamReader (new FileInputStream(file), charset)); 
    String line; 
    while((line = in.readLine()) != null) { 
    .... 
    } 

Ở đó bạn có văn bản giải mã. Bạn có thể viết nó bằng phương thức simmetric Writer/OutputStream, với mã hóa bạn thích (ví dụ UTF-8).

+0

Không nhất thiết phải đọc từng dòng – OscarRyz

+2

tất nhiên là không, đó chỉ là một cách dễ hiểu. – leonbloy

+0

vấn đề tiềm năng với việc đọc từng dòng là bạn có thể thay đổi kết thúc/tách dòng. Ví dụ: nếu dòng cuối cùng không có dòng cuối, bạn sẽ thêm một dòng. –

1

Bạn chỉ muốn đọc nó như là UTF-8? Điều gần đây tôi đã đưa ra một vấn đề tương tự là bắt đầu JVM bằng -Dfile.encoding = UTF-8 và đọc/in như bình thường. Tôi không biết nếu đó là áp dụng trong trường hợp của bạn.

Với tùy chọn rằng:

System.out.println("á é í ó ú") 

in một cách chính xác các ký tự. Nếu không nó sẽ in? symbol

+2

http : //bugs.sun.com/view_bug.do? bug_id = 4163515 – McDowell

+0

@McD: Tôi sẽ đăng cùng một nhận xét. Đây là một sự giải thích sai về việc sử dụng '-Dfile.encoding'. – BalusC

+0

Tôi hiểu, nó thực sự là một mớ hỗn độn. – Ismael

4

Bạn cần biết mã hóa của tệp đầu vào. Ví dụ, nếu tập tin là trong Latin-1, bạn sẽ làm một cái gì đó như thế này,

 FileInputStream fis = new FileInputStream("test.in"); 
     InputStreamReader isr = new InputStreamReader(fis, "ISO-8859-1"); 
     Reader in = new BufferedReader(isr); 
     FileOutputStream fos = new FileOutputStream("test.out"); 
     OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); 
     Writer out = new BufferedWriter(osw); 

     int ch; 
     while ((ch = in.read()) > -1) { 
      out.write(ch); 
     } 

     out.close(); 
     in.close(); 
+2

Tóm tắt: ** đọc ** nó trong mã hóa riêng của tập tin và sau đó ** ghi ** nó trong bảng mã mới. – BalusC

14

Các mã sau chuyển đổi một tập tin từ srcEncoding để tgtEncoding:

public static void transform(File source, String srcEncoding, File target, String tgtEncoding) throws IOException { 
    BufferedReader br = null; 
    BufferedWriter bw = null; 
    try{ 
     br = new BufferedReader(new InputStreamReader(new FileInputStream(source),srcEncoding)); 
     bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding)); 
     char[] buffer = new char[16384]; 
     int read; 
     while ((read = br.read(buffer)) != -1) 
      bw.write(buffer, 0, read); 
    } finally { 
     try { 
      if (br != null) 
       br.close(); 
     } finally { 
      if (bw != null) 
       bw.close(); 
     } 
    } 
} 

--EDIT--

Sử dụng Try-với-nguồn (Java 7):

public static void transform(File source, String srcEncoding, File target, String tgtEncoding) throws IOException { 
    try (
     BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(source), srcEncoding)); 
     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding));) { 
      char[] buffer = new char[16384]; 
      int read; 
      while ((read = br.read(buffer)) != -1) 
       bw.write(buffer, 0, read); 
    } 
} 
+2

Bỏ qua bình luận của tôi, bạn nói đúng.Btw, đã không nhìn thấy phong cách này của đóng cửa cuối cùng trước. Tài giỏi. – BalusC

Các vấn đề liên quan