Запись в файл с кодировкой ISO-8859-1

У меня есть код vb6, который упорно пишет в Windows-1252.

  Open fileName For Binary Access Write As #fileNo
  Put #fileNo, , contents
  Close #fileNo

Сделав это, мне удалось заставить его писать в UTF-16 (LE);

contents = ChrW$(&HFEFF&) & contents

Можно ли как-то легко заставить его писать в ISO-8859-1? Примеры/предложения будут очень признательны здесь.


person cc0    schedule 30.11.2011    source источник
comment
Помещение поддельной спецификации в начале не волшебным образом делает ее UTF-16. Вам также необходимо изменить запись данных для вывода необработанных данных Unicode.   -  person Deanna    schedule 30.11.2011
comment
Вы абсолютно правы, и это грязное исправление =]   -  person cc0    schedule 30.11.2011
comment
это не исправление, это откровенная ложь. Текст по-прежнему будет закодирован как локальный набор символов, если вы не запишете данные (не строку)   -  person Deanna    schedule 30.11.2011
comment
@Deanna: Ты уверен в этом? Я не могу найти никакой документации, объясняющей это, но, предположительно, конкатенация строки широких символов с обычной строкой является строкой широких символов (с продвижением/расширением символов обычной строки). Если Put счастливо записывает x{FEFF} как \xFF\xFE (маленький порядок следования байтов UTF-16), как следует из вопроса, то это предполагает, что (например) \x20 будет записано как \x20\x00. Другими словами, я предполагаю, что он записывает подлинный UTF-16LE, а не просто ASCII, которому предшествует UTF-16LE BOM.   -  person ruakh    schedule 30.11.2011
comment
@руах: Да. Строки VB ВСЕГДА внутренне имеют юникод, но преобразуются в локальный набор символов, когда выходят за пределы его контроля, например. в файл или API. Поскольку content является строкой (массив байтов терпит неудачу из-за несоответствия типов), содержащей wibble, приведенный выше код записывает 77 69 62 62 6C 65. Добавление поддельной спецификации в строку просто приводит к тому, что она добавляет 3F к началу двоичных данных.   -  person Deanna    schedule 30.11.2011
comment
Если вы хотите продолжить обсуждение...   -  person Deanna    schedule 30.11.2011
comment
@Deanna: Вы говорите, что спецификация преобразуется в вопросительный знак ASCII. Но если это так - если он даже не успешно записывает спецификацию, не говоря уже о записи остальной части файла в формате UTF-16, то почему OP говорит, что ему удалось заставить его писать в UTF-16 ( ЛЭ)?   -  person ruakh    schedule 30.11.2011
comment
@ruakh: Точно. Кто знает, что они получили, поскольку они кажутся очень расплывчатыми в деталях. Это будет правильно UTF-16 (я думаю), если содержимое было массивом байтов, но тогда они не могут выполнять конкатенацию строк на нем.   -  person Deanna    schedule 30.11.2011
comment
@Deanna: Я знаю, что вы упрощали, но эти преобразования ANSI имеют мало общего с тем, что выходит из-под контроля VB. Они выполняются преднамеренно, и в первую очередь для того, чтобы VB6 мог перейти на Unicode, сохранив при этом совместимость с Win9x и старыми файлами данных. К сожалению, мы так и не получили VB7, который помог бы нам в дальнейшем переходе, а только хлипкий FSO в качестве временной меры.   -  person Bob77    schedule 01.12.2011
comment
Интересная дискуссия, всем спасибо. Я кое-что узнал.   -  person cc0    schedule 01.12.2011


Ответы (3)


Если ваши файлы невелики, ADO может прийти на помощь для быстрой и грязной обработки нечетных кодировок.

Пример:

Option Explicit

Private Sub Main()
    Const contents As String = "Hello World.  (4 × 6) ÷ 8 = 3 €€€ ƒƒƒ"
    Dim Stm As ADODB.Stream

    Set Stm = New ADODB.Stream
    With Stm
        .Open
        .Type = adTypeText
        .Charset = "iso-8859-1"
        .LineSeparator = adLF
        .WriteText contents, adWriteLine
        .SaveToFile "ISO-8859-1.txt", adSaveCreateOverWrite
        .Close

        .Open
        .Type = adTypeText
        .Charset = "windows-1252"
        .LineSeparator = adCRLF
        .WriteText contents, adWriteLine
        .SaveToFile "Windows-1252.txt", adSaveCreateOverWrite
        .Close
    End With
    MsgBox "Done"
End Sub
person Bob77    schedule 30.11.2011
comment
Насколько я знаю, спецификация применяется только к Unicode, и если вы хотите ISO-8859-1, то спецификация не имеет смысла. - person Bob77; 01.12.2011
comment
Я также должен отметить контроль над концами строк. Вы можете выбрать между CR, LF и CRLF. Вы даже можете использовать это для чтения закодированных файлов. - person Bob77; 01.12.2011

Windows-1252, по сути, является расширенным набором ISO-8859-1; просто запишите свои данные как Windows-1522 и не используйте символы Windows-1252, которые не являются символами ISO-8859-1.

person ruakh    schedule 30.11.2011
comment
Это была и моя первоначальная мысль, однако мои коллеги не приняли ее как решение. Любые другие мысли? - person cc0; 30.11.2011
comment
Как ваши коллеги определяют кодировку файла? То есть, как они решают, что ваш выходной файл - это Windows-1252, а не ISO-8859-1, который им нужен? (Возможно ли, что вы неправильно понимаете их проблему?) - person ruakh; 30.11.2011
comment
У них есть некоторое старое программное обеспечение, с которым, как они утверждают, у них были определенные проблемы с Windows-1252. Это все, что я знаю, и они отказываются сдвинуться с места. Я думаю просто написать простой инструмент С# для преобразования после первого письма. Глупо, но, возможно, не глупее, чем тратить много времени на поиск решения vb6. - person cc0; 30.11.2011
comment
В этом случае просто скажите им, что вы отправляете им ISO-8859-1. Это правда. (Но на всякий случай вам следует написать простой инструмент C#, чтобы убедиться, что он действительно соответствует стандарту ISO-8859-1!) - person ruakh; 30.11.2011

Вывод символов VB6 кодируется в машинной кодовой странице по умолчанию для программ, отличных от Unicode.

  • Если вам удастся установить кодовую страницу вашего компьютера на 28591, которая является кодовой страницей Windows для iso-8859-1, то вы можете быть абсолютно уверены, что ваш вывод будет iso-8859-1
  • В качестве альтернативы просто избегайте символов, в которых Windows 1252 отличается от ISO-8859-1. Википедия говорит, что это от 128 до 159. Вы можете обнаружить их и заменить вопросительными знаками или выдать ошибку.
person MarkJ    schedule 30.11.2011
comment
Знаки вопроса подходят для некоторых вещей, таких как знак евро (€), но в некоторых случаях требуется перевод, например. от ƒ до ф. - person Bob77; 01.12.2011