2010-04-07 25 views
15

Tôi đang gửi tệp văn bản được lưu ở định dạng ISO 88591-1 chứa các ký tự có dấu trọng âm từ dải Latinh-1 như az ASC bình thường, v.v.) Làm cách nào để chuyển đổi các tệp này thành UTF-8 bằng C# sao cho các ký tự có dấu một byte trong ISO 8859-1 trở thành các ký tự UTF-8 hợp lệ?Sử dụng .NET cách chuyển đổi các tệp văn bản được mã hóa ISO 8859-1 chứa các ký tự có dấu Latin-1 thành UTF-8

Tôi đã cố gắng sử dụng một StreamReader với ASCIIEncoding, và sau đó chuyển đổi chuỗi ASCII sang UTF-8 bởi instantiating mã hóa và mã hóa asciiutf8 và sau đó sử dụng Encoding.Convert(ascii, utf8, ascii.GetBytes(asciiString)) — nhưng ký tự có dấu được trả lại như dấu hỏi.

Tôi đang bỏ lỡ bước nào?

+0

Các bạn đã cố gắng sử dụng một StreamWriter với mã hóa UTF8 để viết asciiString ra một tệp văn bản? Điều đó có làm được không? – Task

+0

@Task: Vấn đề của anh ta là anh ta không bao giờ nhận được chuỗi từ 8859-1, không phải là anh ta không thể lưu nó trong UTF-8. –

+0

Ồ, đó hoàn toàn là vấn đề của anh ấy, không có câu hỏi. Tôi chỉ tìm thấy dễ dàng hơn để gỡ lỗi chuyển đổi văn bản với một cặp StreamReader/StreamWriter (vì vậy tôi có thể thấy các tệp vào/ra) thay vì bằng một cuộc gọi Encoding.Convert. Đó có thể chỉ là tôi. – Task

Trả lời

32

Bạn cần nhận đối tượng Encoding thích hợp. ASCII giống như tên của nó: ASCII, có nghĩa là nó chỉ hỗ trợ các ký tự ASCII 7 bit. Nếu những gì bạn muốn làm là chuyển đổi các tập tin, thì điều này có thể dễ dàng hơn là xử lý trực tiếp các mảng byte.

using (System.IO.StreamReader reader = new System.IO.StreamReader(fileName, 
             Encoding.GetEncoding("iso-8859-1"))) 
{ 
    using (System.IO.StreamWriter writer = new System.IO.StreamWriter(
              outFileName, Encoding.UTF8)) 
    { 
     writer.Write(reader.ReadToEnd()); 
    } 
} 

Tuy nhiên, nếu bạn muốn có mảng byte, bạn có thể dễ dàng thực hiện với Encoding.Convert.

byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), 
    Encoding.UTF8, data); 

Điều quan trọng cần lưu ý ở đây, tuy nhiên, nếu bạn muốn đi theo con đường này thì bạn nên không sử dụng một đầu đọc chuỗi mã hóa dựa trên như StreamReader cho tập tin của bạn IO. FileStream sẽ phù hợp hơn, vì nó sẽ đọc các byte thực của các tệp.

Trong sự quan tâm khám phá hoàn toàn vấn đề này, một cái gì đó như thế này sẽ làm việc:

using (System.IO.FileStream input = new System.IO.FileStream(fileName, 
            System.IO.FileMode.Open, 
            System.IO.FileAccess.Read)) 
{ 
    byte[] buffer = new byte[input.Length]; 

    int readLength = 0; 

    while (readLength < buffer.Length) 
     readLength += input.Read(buffer, readLength, buffer.Length - readLength); 

    byte[] converted = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), 
         Encoding.UTF8, buffer); 

    using (System.IO.FileStream output = new System.IO.FileStream(outFileName, 
             System.IO.FileMode.Create, 
             System.IO.FileAccess.Write)) 
    { 
     output.Write(converted, 0, converted.Length); 
    } 
} 

Trong ví dụ này, biến buffer được lấp đầy với các dữ liệu thực tế trong file như một byte[], vì vậy không chuyển đổi là làm xong. Encoding.Convert chỉ định mã hóa nguồn và đích, sau đó lưu trữ các byte được chuyển đổi trong biến có tên ... converted. Điều này sau đó được ghi trực tiếp vào tệp đầu ra. Giống như tôi đã nói, tùy chọn đầu tiên sử dụng StreamReaderStreamWriter sẽ đơn giản hơn nhiều nếu đây là tất cả những gì bạn đang làm, nhưng ví dụ sau sẽ cho bạn nhiều gợi ý hơn về những gì đang thực sự xảy ra.

+0

nhờ tất cả vì sự giúp đỡ và đặc biệt @Adam cho câu trả lời kỹ lưỡng của mình – Tim

10

Nếu các tập tin là tương đối nhỏ (nói, ~ 10 MB), bạn sẽ chỉ cần hai dòng mã:

string txt = System.IO.File.ReadAllText(inpPath, Encoding.GetEncoding("iso-8859-1")); 
    System.IO.File.WriteAllText(outPath, txt); 
+0

làm việc cho tôi .. –

+0

Đối với tôi. – Cheloide

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