Файл проекта Visual Studio 2008 не загружается из-за неожиданного изменения кодировки

В нашей команде есть проект базы данных в Visual Studio 2008, который находится под управлением Team Foundation Server. Каждые две недели или около того, после регистрации одного сотрудника, файл проекта не загружается на другие компьютеры разработчиков. Сообщение об ошибке:

Не удалось загрузить файл проекта. Данные на корневом уровне недействительны. Линия 1, позиция 1.

Когда я смотрю на файл проекта в Notepad++, он выглядит так:

��<NUL?NULxNULmNULlNUL NULvNULeNULrNULsNULiNULoNULnNUL ...

и так далее (здесь вы видите <?xml version), в то время как обычный файл проекта выглядит так:

<?xml version="1.0" encoding="utf-16"?> ...

Так что, вероятно, что-то не так с кодировкой файла. Это проблема для нас, потому что оказывается невозможным снова получить правильную кодировку файла. «Решение» состоит в том, чтобы выбросить файл проекта и получить последнюю известную рабочую версию из системы управления версиями.

Согласно файлу кодировка должна быть UTF-16. Согласно Notepad++, поврежденный файл на самом деле имеет кодировку UTF-8.

Мои вопросы:

  • Почему Visual Studio портит кодировку файла проекта, по-видимому, в случайное время и на случайных машинах?
  • Что мы должны сделать, чтобы предотвратить это?
  • Когда это произошло, есть ли возможность восстановить текущий файл в правильной кодировке вместо того, чтобы извлекать более старую версию из системы управления версиями?

И последнее замечание: проблема связана с одним единственным файлом проекта, все остальные файлы проекта не раскрывают эту проблему.

ОБНОВЛЕНИЕ: Благодаря предложению Джона Скита у меня есть ответ на вопрос номер три. Когда я заменю первые девять байтов EF BB BF EF BF BD EF BF BD на два байта FF FE, файл проекта снова загрузится.

Это все еще оставляет вопрос, почему Visual Studio повреждает файл.


person Xenan    schedule 23.03.2010    source источник
comment
Что вы увидите, если проведете двоичный анализ между сломанными и рабочими файлами? Интересно, это проблема порядка байтов UTF-16.   -  person Jon Skeet    schedule 23.03.2010
comment
Если я делаю бинарный diff, то получается, что файлы идентичны, за исключением того, что правильный имеет два лишних байта в начале, FF FE, а поврежденный - девять дополнительных байтов EF BB BF EF BF BD EF BF BD.   -  person Xenan    schedule 23.03.2010


Ответы (1)


Я думаю, что могу дать некоторое представление о том, что происходит, если не почему.

FF FE – это спецификация; его присутствие в начале файла указывает на то, что файл имеет кодировку UTF-16, обратный порядок байтов. И похоже, что исходный файл действительно UTF-16, но что-то игнорирует спецификацию и читает ее, как если бы это была UTF-8.

Когда это происходит, каждый из байтов FF и FE считается недопустимым и преобразуется в U+FFFD, официальный мусорный символ Unicode. Затем, когда текст снова записывается в файл, каждый из мусорных символов преобразуется в свою кодировку UTF-8 (EF BF BD), а перед ними добавляется спецификация UTF-8 (EF BB BF). , в результате чего получается последовательность из девяти байтов, о которой вы сообщили:

EF BB BF  # UTF-8 BOM
EF BF BD  # U+FFFD in UTF-8
EF BF BD  # ditto

Если это так, простая замена этих девяти байтов на FF FE небезопасна. Нет никакой гарантии, что это единственные байты в файле, которые будут недействительными при интерпретации как UTF-8. Пока файл содержит только символы ASCII, все в порядке, но все остальное, например символы с диакритическими знаками (é) или фигурные кавычки (), будут безвозвратно искажены.

Действительно ли файлы проекта должны быть UTF-16? Если нет, возможно, система одного разработчика генерирует UTF-16, когда система контроля версий ожидает UTF-8. Я заметил, что в моей установке Visual C# Express есть опция под Environment->Documents под названием «Сохранить документы как Unicode, когда данные не могут быть сохранены в кодовой странице». Это звучит как что-то, что может привести к изменению кодировки в случайное время.

person Alan Moore    schedule 24.03.2010
comment
Спасибо, это действительно дает некоторое представление. - person Xenan; 25.03.2010