← Tất cả bài viết

Lỗi tên file ZIP trên Windows khi nhận từ máy Mac

Nếu bạn nhận file ZIP từ máy Mac rồi mở trên Windows và thấy tên file bị lỗi dấu, thường chỉ có hai nguyên nhân, và cả hai đều sửa được mà không làm thay đổi nội dung tài liệu. Một là file ZIP lưu tên bằng bảng mã mà Windows đọc sai (bạn thấy những chuỗi như Nguyá»…n Văn An.docx). Hai là tên file được lưu theo dạng Unicode tách rời mà macOS hay dùng, nên các chữ có dấu bị tách thành nhiều phần (Nguyeˆ~n, Hợp đồng thành các ký tự ghép lẻ). Trường hợp đầu sửa bằng cách giải nén bằng công cụ khác. Trường hợp sau sửa bằng cách chuẩn hóa tên file về dạng NFC, bạn có thể làm trên trình duyệt hoặc chạy một lệnh PowerShell ngắn. Các bước bên dưới hướng dẫn cả hai.

Vì sao tên file ZIP bị lỗi khi chuyển từ Mac sang Windows

Định dạng ZIP lưu mỗi tên file dưới dạng dãy byte, kèm một cờ nhỏ cho biết dãy byte đó có phải UTF-8 hay không. Nội dung bên trong file không bị ảnh hưởng, nên khi mở được file thì tài liệu vẫn đầy đủ. Chỉ có phần tên bị hỏng.

Tình huống thường gặp như sau. Đồng nghiệp dùng Mac, vào Finder, chọn thư mục rồi bấm Nén (Compress), sau đó gửi cho bạn file .zip qua email hoặc Zalo. Bạn nhấp đúp trong Windows Explorer, chọn Extract All (Giải nén tất cả), và trong thư mục vừa hiện ra có những tên như:

  • Zoe¨_hóa đơn.xlsx thay vì Zoë_hóa đơn.xlsx
  • Nguyeˆ~n Văn An.pdf thay vì Nguyễn Văn An.pdf
  • Hợp đồng lao động.docx hiển thị với dấu tách rời trong một số ứng dụng
  • がいよう.pptx hiển thị thành か゛いよう.pptx

Ở trường hợp khác, tên file hiển thị hoàn toàn khó đọc, ví dụ Nguyá»…n Văn An.pdf.

Đây là hai lỗi khác nhau nhưng trông khá giống nhau:

Lỗi bảng mã (mojibake). Phần mềm nén ghi tên bằng UTF-8 nhưng không đánh dấu đúng, và trình giải nén của Windows đọc theo bảng mã cũ của hệ thống. Kết quả là chuỗi chữ cái có dấu lạ và ký hiệu không liên quan đến tên gốc. Tên file vẫn còn nguyên, chỉ bị giải mã sai.

Unicode tách rời (NFD). macOS thường lưu chữ có dấu thành nhiều ký tự riêng. Chữ ê thành e cộng với dấu mũ, chữ ễ thành e cộng với dấu mũ và dấu ngã, còn が thành か cộng với dấu nháy. Tên như vậy vẫn hợp lệ về mặt Unicode và Windows vẫn mở được, nhưng Windows, phần lớn biểu mẫu web và máy chủ đều mong đợi dạng ghép sẵn (NFC). Vì vậy chữ hiển thị sai, tìm kiếm trong Explorer không ra, các script so sánh tên file có thể lỗi, và form tải lên đôi khi từ chối hoặc coi là hai file khác nhau. Đây là trường hợp Nguyeˆ~n và ㅎㅏㄴㄱㅡㄹ ở trên.

Phân biệt hai lỗi này chỉ mất khoảng mười giây, nên hãy làm bước này trước.

Bước 1: xác định bạn đang gặp lỗi nào

Mở thư mục đã giải nén (hoặc xem trực tiếp file ZIP trong Explorer mà chưa giải nén) rồi nhìn vào một tên bị lỗi.

  1. Nếu tên có những ký tự rõ ràng không thuộc bất kỳ từ nào, như é, á», ’, thì đó là lỗi bảng mã. Chuyển sang phần Cách B.
  2. Nếu tên đọc được nhưng dấu bị tách ra, hoặc chữ Hàn và Nhật hiện thành từng phụ âm và nguyên âm riêng lẻ, thì đó là NFD. Kiểm tra nhanh như sau:
    • Chuột phải vào file và chọn Rename (Đổi tên).
    • Bấm phím End rồi bấm Backspace một lần.
    • Nếu chỉ mất dấu (hoặc chỉ mất nguyên âm/nét phụ) mà chữ gốc vẫn còn, tên đó đang ở dạng tách rời. Với tên chuẩn NFC, một lần Backspace sẽ xóa cả chữ có dấu.
    • Với chữ như ễ ở dạng tách rời, có thể phải bấm Backspace nhiều lần mới xóa hết.

Nếu bạn quen dùng PowerShell, lệnh sau cho kết quả trực tiếp:

Get-ChildItem -Recurse -File | Where-Object {
  -not $_.Name.IsNormalized([Text.NormalizationForm]::FormC)
} | Select-Object FullName

Các file được liệt kê ra đều đang ở dạng NFD.

Cách sửa tên file ZIP bị tách dấu (NFD)

Có hai cách hợp lý. Cách thứ nhất làm hoàn toàn trên trình duyệt và giữ nguyên file ZIP. Cách thứ hai đổi tên file sau khi đã giải nén.

Cách 1: sửa tên ngay trong file ZIP trên trình duyệt

Cách này ít thao tác nhất nếu bạn muốn chuyển tiếp file ZIP cho người khác hoặc giữ nguyên bản nén.

  1. Mở công cụ khôi phục tên file ZIP trên trình duyệt.
  2. Kéo file .zip từ thư mục Downloads thả vào trang (hỗ trợ file đến 200 MB).
  3. Công cụ sẽ đổi tên các file bên trong từ NFD sang NFC và cho bạn tải về một file ZIP đã sửa.
  4. Giải nén file ZIP mới bằng Extract All như bình thường. Các tên như Nguyễn Văn An.pdf và Hợp đồng lao động.docx sẽ hiển thị đúng, và tìm kiếm trong Explorer cũng sẽ ra kết quả.

Việc xử lý diễn ra trên trình duyệt của bạn. File và tên file không được tải lên máy chủ, điều này quan trọng khi ZIP chứa hợp đồng khách hàng hoặc hồ sơ nhân sự. Công cụ miễn phí. Nếu bạn đã giải nén và chỉ còn các file rời, cũng trang đó có chức năng kéo thả để đổi tên hàng loạt.

Cách 2: đổi tên sau khi giải nén bằng PowerShell

Windows đã có sẵn mọi thứ cần thiết để chuẩn hóa tên file, vì .NET đã hỗ trợ chuẩn hóa Unicode từ nhiều năm nay. Hãy làm việc trên một bản sao của thư mục trước, vì lệnh này đổi tên trực tiếp.

  1. Giải nén file ZIP như bình thường.
  2. Mở thư mục vừa giải nén, bấm vào thanh địa chỉ, gõ powershell rồi nhấn Enter. Cửa sổ PowerShell sẽ mở ngay trong thư mục đó.
  3. Dán đoạn lệnh sau và nhấn Enter:
Get-ChildItem -Recurse -File | ForEach-Object {
  $nfc = $_.Name.Normalize([Text.NormalizationForm]::FormC)
  if ($nfc -ne $_.Name) {
    Rename-Item -LiteralPath $_.FullName -NewName $nfc
  }
}
  1. Nếu tên thư mục cũng bị lỗi, chạy lại lệnh với -Directory thay cho -File. Hãy đổi tên thư mục con sau khi đã đổi tên các file bên trong, nếu không đường dẫn sẽ thay đổi giữa chừng.

Cách này phù hợp với trường hợp xử lý một lần, hoặc với lập trình viên muốn đưa vào script build. Nhược điểm là nó không tác động gì đến file ZIP gốc, và dễ chạy nhầm ở thư mục khác nếu bạn không để ý.

Cách sửa lỗi bảng mã trong tên file ZIP

Nếu bạn thấy lỗi kiểu Nguyá»…n, việc chuẩn hóa sẽ không giúp gì, vì cần giải mã các byte đúng theo UTF-8 ngay từ đầu.

  1. Cài 7-Zip (miễn phí, tải từ 7-zip.org) hoặc một trình nén bên thứ ba khác. Những công cụ này thường đọc đúng tên UTF-8 ngay cả khi thiếu cờ UTF-8, đây là chỗ trình giải nén mặc định của Explorer hay bị lỗi.
  2. Chuột phải vào file ZIP, chọn 7-Zip → Extract Here (hoặc Extract to "tên thư mục").
  3. Kiểm tra tên file. Nếu đã đọc được, bạn xong rồi.
  4. Nếu tên đọc được nhưng dấu hoặc chữ Hàn vẫn bị tách, nghĩa là bạn đang gặp cả hai lỗi. Quay lại Cách 1 hoặc Cách 2 của phần trên để chuẩn hóa các file đã giải nén.

Nếu trình giải nén bên thứ ba vẫn cho ra chuỗi vô nghĩa, có nghĩa là bên gửi đã dùng một bảng mã cũ thay vì UTF-8. Lúc đó cách nhanh nhất là nhờ người gửi nén lại. Trên Mac, lệnh Nén có sẵn và hầu hết ứng dụng nén bên thứ ba đều ghi UTF-8. Lỗi thường xuất phát từ một công cụ cũ hoặc lạ, hoặc từ một file ZIP được nén lại trên máy Windows có cài ngôn ngữ hệ thống khác.

Tránh lỗi này trong các lần sau

Vài thói quen dưới đây giúp loại bỏ phần lớn lỗi này, ở cả hai phía khi trao đổi file.

Nếu bạn là người gửi từ Mac: trước khi nén, bạn có thể dùng một công cụ chuẩn hóa tên để các file đã ở dạng NFC. Hoặc tránh ZIP hoàn toàn bằng cách chia sẻ liên kết từ dịch vụ lưu trữ đám mây. Hầu hết dịch vụ này có chuẩn hóa tên khi tải lên, nhưng không phải tất cả, nên hãy thử một file mẫu trước. Với file tải lên qua biểu mẫu web chứ không qua ZIP, tiện ích Chrome FilenameFixer sẽ tự chuyển tên sang NFC khi tải lên. Nhờ vậy, biểu mẫu của người nhận không từ chối Zoë.xlsx chỉ vì nó không khớp với tên Zoë đã có sẵn trong hệ thống của họ.

Nếu bạn nhận file trên Windows: hãy cài sẵn 7-Zip hoặc công cụ tương tự. Khi nhận file ZIP từ Mac có tên tiếng Hàn, tiếng Nhật hoặc tiếng Việt, hãy làm thử bước Backspace mười giây trước khi bỏ công sức đổi tên bằng tay. Đổi tên bằng tay ở đây đặc biệt dễ sai, vì trong hầu hết phông chữ, tên ở dạng tách rời và tên ở dạng ghép sẵn trông giống hệt nhau. Bạn có thể kết thúc với hai file trông như cùng một tên.

Nếu bạn là lập trình viên: hãy chuẩn hóa về NFC ngay tại điểm tiếp nhận dữ liệu của ứng dụng, dù đó là bộ xử lý tải file, script đồng bộ hay bước build. Python có unicodedata.normalize("NFC", name), Node có name.normalize("NFC"), còn .NET có String.Normalize(). Làm vậy tốn ít công sức hơn nhiều so với việc đi tìm lý do vì sao một bài test chạy được trên macOS nhưng lỗi trên máy CI chạy Linux, chỉ vì hai tên file "giống hệt nhau" thực ra là hai dãy byte khác nhau.

Không có cách nào trong số này làm thay đổi nội dung tài liệu, nên không có rủi ro với dữ liệu bên trong. Tệ nhất khi đoán sai là bạn phải giải nén file ZIP thêm một lần nữa.