Как создать и записать текстовый файл UTF-16 с помощью Applescript?

Я пишу Applescript для анализа файла локализации iOS (/en.lproj/Localizable.strings), перевода значений и вывода перевод (/fr.lproj/Localizable.strings) на диск в кодировке UTF-16 (Unicode).

По какой-то причине сгенерированный файл имеет лишний пробел между каждой буквой. Немного покопавшись, я нашел причину проблемы в книге Learn AppleScript: The Comprehensive Guide to Scripting.

«Если вы случайно прочитали файл UTF-16 как MacRoman, результирующее значение на первый взгляд может выглядеть как обычная строка, особенно если оно содержит текст на английском языке. Вы быстро обнаружите, что что-то не так, когда попытаетесь его использовать, однако: общий симптом заключается в том, что перед каждым видимым символом в вашей «строке» находится невидимый символ. Например, чтение текстового файла в кодировке UTF-16, содержащего фразу «Hello World!», в качестве строки приводит к строка типа «Привет, мир! ", где каждый " " на самом деле является невидимым символом ASCII 0."

Так, например, мой строковый файл английской локализации имеет:

"Yes" = "Yes";

И сгенерированный строковый файл французской локализации имеет:

 " Y e s "  =  " O u i " ;

Вот мой метод createFile:

on createFile(fileFolder, fileName)
    tell application "Finder"
        if (exists file fileName of folder fileFolder) then
            set the fileAccess to open for access file fileName of folder fileFolder with write permission
            set eof of fileAccess to 0
            write ((ASCII character 254) & (ASCII character 255)) to fileAccess starting at 0
            --write «data rdatFEFF» to fileAccess starting at 0
            close access the fileAccess
        else
            set the filePath to make new file at fileFolder with properties {name:fileName}
            set the fileAccess to open for access file fileName of folder fileFolder with write permission
            write ((ASCII character 254) & (ASCII character 255)) to fileAccess starting at 0
            --write «data rdatFEFF» to fileAccess starting at 0
            close access the fileAccess
        end if
        return file fileName of folder fileFolder as text
    end tell
end createFile

А вот мой метод writeFile:

on writeFile(filePath, newLine)
    tell application "Finder"
        try
            set targetFileAccess to open for access file filePath with write permission
            write newLine to targetFileAccess as Unicode text starting at eof
            close access the targetFileAccess
            return true
        on error
            try
                close access file filePath
            end try
            return false
        end try
    end tell
end writeFile

Любая идея, что я делаю неправильно?


person Dale Zak    schedule 13.02.2011    source источник
comment
Я думаю, что перевод этого вручную занял бы меньше времени, чем написание этого AppleScript, который даже не работает. :')   -  person    schedule 13.02.2011
comment
Радек, более 150+ фраз, которые нужно перевести на 10+ языков...   -  person Dale Zak    schedule 13.02.2011
comment
Вы все равно должны ввести их когда-нибудь.   -  person    schedule 13.02.2011


Ответы (2)


Вот обработчики, которые я использую для чтения и записи в формате UTF16. Вам не нужен отдельный обработчик «создать файл». Обработчик записи создаст файл, если он не существует. Установите для переменной «appendText» значение true или false. False означает перезапись файла, а true означает добавление нового текста в конец текущего текста в файле. Надеюсь, это поможет.

on writeTo_UTF16(targetFile, theText, appendText)
    try
        set targetFile to targetFile as text
        set openFile to open for access file targetFile with write permission
        if appendText is false then
            set eof of openFile to 0
            write (ASCII character 254) & (ASCII character 255) to openFile starting at eof -- UTF-16 BOM
        else
            tell application "Finder" to set fileExists to exists file targetFile
            if fileExists is false then
                set eof of openFile to 0
                write (ASCII character 254) & (ASCII character 255) to openFile starting at eof -- UTF-16 BOM
            end if
        end if
        write theText to openFile starting at eof as Unicode text
        close access openFile
        return true
    on error theError
        try
            close access file targetFile
        end try
        return theError
    end try
end writeTo_UTF16

on readFrom_UTF16(targetFile)
    try
        set targetFile to targetFile as text
        targetFile as alias -- if file doesn't exist then you get an error
        set openFile to open for access file targetFile
        set theText to read openFile as Unicode text
        close access openFile
        return theText
    on error
        try
            close access file targetFile
        end try
        return false
    end try
end readFrom_UTF16
person regulus6633    schedule 13.02.2011
comment
Спасибо, regulus6633, я проверю и дам вам знать, как это работает! - person Dale Zak; 14.02.2011

Если вы получаете фактические пробелы между каждым символом, у вас, вероятно, есть анти-шаблон «(символы от i до j в некотором тексте) как строка» в вашем коде [1]. Это разделит строку на список символов, а затем вернет ее обратно в строку с вашим текущим разделителем текстового элемента, вставленным между каждым символом. Правильный (т.е. быстрый и безопасный) способ получить подстроку таков: 'текст от i до j некоторого текста' (стр. 179-181).

OTOH, если вы получаете невидимые символы между каждым символом [2], тогда да, это будет проблемой кодировки, обычно при чтении файла в кодировке UTF16 с использованием MacRoman или другой однобайтовой кодировки. Если ваш файл имеет допустимую метку порядка байтов, то любой текстовый редактор, умеющий работать с Unicode, должен прочитать его, используя правильную кодировку.


[1] p179 заявляет, что эта идиома небезопасна, но забывает предоставить практическую демонстрацию проблем, которые она вызывает. [3]

[2] IIRC пример на стр. 501 предназначался для использования прямоугольных символов для представления невидимых символов, то есть «⃞H⃞e⃞l⃞l⃞o», а не «H e l l o», но получилось не совсем так, поэтому может быть неправильно истолковано как означающее видимые пробелы. [3]

[3] Не стесняйтесь отправлять исправления в Apress.

person has    schedule 15.02.2011