Как мне записать сжатую строку LZ в текстовый файл, используя JXA? - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь написать сценарий JXA в Apple Script Editor, который сжимает строку с использованием алгоритма LZ и записывает ее в текстовый файл (JSON):

var story = "Once upon a time in Silicon Valley..."
var storyC = LZString.compress(story)
var data_to_write = "{\x22test\x22\x20:\x20\x22"+storyC+"\x22}"
app.displayAlert(data_to_write)
var desktopString = app.pathTo("desktop").toString()
var file = `${desktopString}/test.json`
writeTextToFile(data_to_write, file, true)

Все работает, кроме того, чтоСжатая строка LZ просто преобразуется в набор "?"к тому времени, когда он достигает выходного файла, test.json .

Он должен выглядеть следующим образом:

{"test" : "㲃냆੠Њޱᐈ攀렒삶퓲ٔ쀛䳂䨀푖㢈Ӱນꀀ"}

Вместо этого он выглядит следующим образом:

{"test" : "????????????????????"}

У меня такое ощущение, что преобразование происходит в команде app.write , используемой функцией writeTextToFile () (которую я извлек из примера в Apple Mac AutomationРуководство по написанию сценариев ):

var app = Application.currentApplication()
app.includeStandardAdditions = true

function writeTextToFile(text, file, overwriteExistingContent) {
    try {

        // Convert the file to a string
        var fileString = file.toString()

        // Open the file for writing
        var openedFile = app.openForAccess(Path(fileString), { writePermission: true })

        // Clear the file if content should be overwritten
        if (overwriteExistingContent) {
            app.setEof(openedFile, { to: 0 })
        }

        // Write the new content to the file
        app.write(text, { to: openedFile, startingAt: app.getEof(openedFile) })

        // Close the file
        app.closeAccess(openedFile)

        // Return a boolean indicating that writing was successful
        return true
    }
    catch(error) {

        try {
            // Close the file
            app.closeAccess(file)
        }
        catch(error) {
            // Report the error is closing failed
            console.log(`Couldn't close file: ${error}`)
        }

        // Return a boolean indicating that writing was successful
        return false
    }
}

Есть ли для app.write команда замены, которая поддерживает сжатую строку LZ / лучший способ выполнить то, что я пытаюсь сделать?

Кроме того, я использую функцию readFile () (также из Scripting Guide ) для загрузки строки LZ обратно в сценарий:

function readFile(file) {
    // Convert the file to a string
    var fileString = file.toString()

    // Read the file and return its contents
    return app.read(Path(fileString))
}

Но вместо того, чтобы возвращать:

{"test" : "㲃냆੠Њޱᐈ攀렒삶퓲ٔ쀛䳂䨀푖㢈Ӱນꀀ"}

Он возвращает:

"{\"test\" : \"㲃냆੠Њޱᐈ攀렒삶퓲ٔ쀛䳂䨀푖㢈Ӱນꀀ\"}"

Кто-нибудь знает исправление для этого тоже?

Я знаю, что можно использовать Какао в сценариях JXA , так что, может быть, в этом и есть решение?

Я только начинаю разбираться с JavaScript, поэтому я признаю, что пытаться понять Objective-C или Swift сейчас далеко от меня.

Я с нетерпением жду любых решений и / или указателейчто вы могли бы предоставить мне.Заранее спасибо!

1 Ответ

0 голосов
/ 12 июня 2019

После некоторого дальнейшего поиска, я наткнулся на эти два сообщения:

Таким образом, я соответствующим образом изменил свой сценарий.

writeTextToFile () теперь выглядит следующим образом:

function writeTextToFile(text, file) {
  // source: https://stackoverflow.com/a/44293869/11616368
  var nsStr       = $.NSString.alloc.initWithUTF8String(text)
  var nsPath      = $(file).stringByStandardizingPath
  var successBool  = nsStr.writeToFileAtomicallyEncodingError(nsPath, false, $.NSUTF8StringEncoding, null)
  if (!successBool) {
    throw new Error("function writeFile ERROR:\nWrite to File FAILED for:\n" + file)
  }
  return successBool  
};

В то время как readFile () выглядит следующим образом:

ObjC.import('Foundation')
const readFile = function (path, encoding) {
  // source: https://github.com/JXA-Cookbook/JXA-Cookbook/issues/25#issuecomment-271204038
    pathString = path.toString()
    !encoding && (encoding = $.NSUTF8StringEncoding)
    const fm = $.NSFileManager.defaultManager
    const data = fm.contentsAtPath(pathString)
    const str = $.NSString.alloc.initWithDataEncoding(data, encoding)
    return ObjC.unwrap(str)
};

Оба используют Objective-C для преодоления app.write и app.read не может обрабатывать UTF-8.

...