2009-06-17 33 views
9

Ứng dụng Win32 Delphi của tôi phân tích các tệp văn bản được tạo bởi các ứng dụng khác không hỗ trợ Unicode. Vì vậy, các ứng dụng của tôi cần đọc và viết các chuỗi ansi, nhưng tôi muốn cung cấp một trải nghiệm người dùng bản địa hóa tốt hơn thông qua việc sử dụng Unicode trong GUI. Ứng dụng này thực hiện một số phân tích chuỗi ký tự theo ký tự khá nặng trong các đối tượng có nguồn gốc từ TList.Chuyển sang Unicode cho ứng dụng xử lý các tệp văn bản

Khi đưa ra việc chuyển đổi sang một giao diện Unicode trong đi từ Delphi 2006 đến Delphi 2009, tôi nên có kế hoạch để:

  1. đi hoàn toàn Unicode trong ứng dụng của tôi, với ngoại lệ của AnsiString tập tin I/O?
  2. đóng gói mã xử lý ansistrings (tức là tiếp tục xử lý chúng dưới dạng ansistrings nội bộ) từ một ứng dụng Unicode khác.

Tôi nhận thấy phản hồi thực sự chi tiết sẽ đòi hỏi một lượng lớn mã của tôi - tôi chỉ hỏi về những lần hiển thị từ những người đã chuyển đổi này và vẫn phải làm việc với tệp văn bản thuần túy. Nơi để đặt rào cản giữa ansistrings và Unicode?

CHỈNH SỬA: nếu # 1, có đề xuất nào để ánh xạ chuỗi Unicode cho đầu ra ansistring không? Tôi đoán rằng việc chuyển đổi các chuỗi đầu vào sẽ được tự động bằng cách sử dụng tstringlist.loadfromfile (ví dụ).

Trả lời

4

Không có thứ gì như đầu ra AnsiString - mỗi tệp văn bản có character encoding. Thời điểm các tệp của bạn chứa các ký tự nằm ngoài phạm vi ASCII bạn phải suy nghĩ về mã hóa, thậm chí tải các tệp đó ở các quốc gia khác nhau sẽ tạo ra các kết quả khác nhau - trừ khi bạn tình cờ sử dụng mã hóa Unicode.

Nếu bạn tải tệp văn bản, bạn cần biết mã hóa của tệp đó. Đối với các định dạng như xml hoặc html thông tin đó là một phần của văn bản, đối với Unicode, có BOM, mặc dù nó không cần thiết đối với các tệp được mã hóa UTF-8.

Chuyển đổi ứng dụng sang Delphi 2009 là cơ hội để suy nghĩ về mã hóa các tệp văn bản và các lỗi trong quá khứ chính xác. Các tệp dữ liệu của một ứng dụng thường có thời lượng lâu hơn các ứng dụng, do đó, nó trả tiền để suy nghĩ về cách làm cho chúng trở nên tương lai và bằng chứng. Tôi khuyên bạn nên sử dụng UTF-8 làm mã hóa tệp văn bản cho tất cả các ứng dụng mới, theo cách đó, việc chuyển ứng dụng sang các nền tảng khác nhau thật dễ dàng. UTF-8 là mã hóa tốt nhất để trao đổi dữ liệu và đối với các ký tự trong phạm vi ASCII hoặc ISO8859-1, nó cũng tạo ra nhiều tệp nhỏ hơn nhiều so với UTF-16 hoặc UTF-32.

Nếu tệp dữ liệu của bạn chỉ chứa các ký tự ASCII, thì tất cả đều được đặt, vì chúng là các tệp được mã hóa UTF-8 hợp lệ. Nếu tệp dữ liệu của bạn có mã hóa ISO8859-1 (hoặc bất kỳ mã hóa cố định nào khác), thì hãy sử dụng chuyển đổi phù hợp trong khi tải chúng vào danh sách chuỗi và lưu chúng trở lại. Nếu bạn không biết trước họ sẽ có mã hóa nào, hãy hỏi người dùng khi tải hoặc cung cấp cài đặt ứng dụng cho mã hóa mặc định.

Sử dụng chuỗi Unicode trong nội bộ. Tùy thuộc vào lượng dữ liệu bạn cần xử lý, bạn có thể sử dụng chuỗi được mã hóa UTF-8.

+0

Tuyệt vời - cách bạn giải thích điều này sẽ giúp ích rất nhiều. Dựa trên sự hiểu biết của tôi, đầu vào thực sự sẽ là các tệp văn bản UTF-8 (ASCII thẳng) và bây giờ có ý nghĩa rằng tôi có thể sử dụng các chuỗi Unicode được mã hóa UTF-8 trong nội bộ. – Argalatyr

+0

Nó không phải là đơn giản để sử dụng UTF-8 chuỗi mã hóa nội bộ, vì vậy tôi không khuyên bạn nên điều này như là một chính sách. Bạn sẽ thấy rằng ngay sau khi bạn bắt đầu sử dụng Stringlists và các hàm chuỗi VCL hữu ích hơn, hàm bạn cần hoặc sẽ không có hoặc sử dụng nó sẽ liên quan đến hai chuyển đổi mã hóa. – frogb

+0

@frogb: Thật vậy, như một chính sách nó sẽ là một ý tưởng tồi. Điều này cần được quyết định theo từng trường hợp cụ thể. Tuy nhiên, nếu không biết mã nào thì nó không thể nói các hàm chuỗi VCL nào là cần thiết, và các biến đổi mã hóa nào sẽ gây ra. – mghie

4

Tôi đề xuất bạn nên sử dụng chế độ unicode đầy đủ nếu cần nỗ lực và yêu cầu. Và giữ tập tin ANSI I/O tách ra khỏi phần còn lại. Nhưng điều này phụ thuộc mạnh mẽ từ ứng dụng của bạn.

3

Bạn nói:

"Ứng dụng hiện một số khá nặng ký tự bằng ký tự phân tích chuỗi trong đối tượng có nguồn gốc từ TList."

Vì Windows chạy Unicode nguyên bản, bạn có thể thấy phân tích ký tự của mình chạy nhanh hơn nếu bạn tải tệp văn bản nội bộ dưới dạng Unicode.

Mặt khác, nếu đó là một tệp lớn, bạn cũng sẽ thấy nó mất gấp đôi bộ nhớ.

Để biết thêm về vấn đề này, xem bài viết Jan Goyvaert của: "Speed Benefits of Using the Native Win32 String Type"

Vì vậy, nó là một sự cân bằng bạn phải quyết định trên.

+0

Cảm ơn bạn đã liên kết. Các tập tin văn bản không phải là rất lớn (một megabyte hoặc hơn). Tôi là một người sử dụng đăng ký hạnh phúc dài hạn của các chương trình JGSoft, vì vậy tôi đã đánh giá cao gấp đôi liên kết này - tôi đã không đọc các bài đăng trên blog của Jan. – Argalatyr

+0

Bạn cũng có thể tìm thấy một số câu trả lời cho câu hỏi mà tôi đã đăng trước đó về việc sử dụng cho bạn. Xem câu trả lời tuyệt vời cho: http://stackoverflow.com/questions/312118/why-the-excess-memory-for-strings-in-delphi bao gồm câu trả lời của Jan. – lkessler

+0

Nếu đầu vào chỉ bao gồm các ký tự ASCII và phân tích ký tự không sử dụng bất kỳ chức năng RTL nào bao bọc API Windows (như được giải thích trong bài viết được liên kết) nhưng chỉ so sánh và công cụ như Pos() thì UnicodeString sẽ chậm hơn AnsiString. – mghie

1

Nếu bạn định lấy đầu vào Unicode từ GUI, chiến lược sẽ là gì để chuyển đổi nó thành đầu ra ASCII? (Đây là một giả định khi bạn đề cập đến văn bản Ansi viết trở lại, giả định cho các ứng dụng không dựa trên Unicode mà bạn sẽ không viết lại và giả định không có mã nguồn cho.) Tôi khuyên bạn nên ở lại với AnsiString trong suốt ứng dụng cho đến khi các ứng dụng khác được bật Unicode. Nếu công việc chính của ứng dụng của bạn là phân tích các tệp loại ASCII không phải Unicode, thì tại sao lại chuyển sang Unicode trong nội bộ? Nếu công việc chính của ứng dụng của bạn liên quan đến việc có một GUI được bật Unicode tốt hơn thì hãy chuyển sang Unicode. Tôi không tin rằng có đủ thông tin được trình bày để quyết định lựa chọn phù hợp.

Nếu không có cơ hội cho các ký tự không dễ dịch được ghi lại cho các ứng dụng không phải Unicode này, thì đề xuất cho UTF-8 là cách có khả năng thực hiện. Tuy nhiên, nếu có cơ hội thì các ứng dụng không phải Unicode sẽ xử lý các ký tự nhiều byte như thế nào? Làm thế nào bạn sẽ chuyển đổi sang (giả định) bộ ký tự ASCII cơ bản?

+0

Hạn chế đầu ra văn bản thành UTF-8/ASCII sẽ không khó (nếu tôi lập kế hoạch tốt) vì nó xuất phát từ đầu vào (trong câu trả lời của mghie này được áp dụng đặc biệt). GUI được sử dụng để tạo ra đầu ra đồ họa (được lưu trong các định dạng vectơ - một vấn đề riêng). Cảm ơn câu trả lời của bạn - giai điệu thận trọng là rất hữu ích trong suy nghĩ về đầu ra văn bản. – Argalatyr

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