Swift - запись байтового потока в файл

У меня есть строка в несколько сотен байт и некоторые значения Int32. Я хочу записать их в файл, дословно.

Я пробовал много предлагаемых решений, и никто не работал на меня. Я получаю посторонние скобки или пробелы или запятые в файле.

Может ли кто-нибудь предложить простое, надежное решение?

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

Как написать и/или добавить "12345" в файл, чтобы файл содержал следующие значения Hex: 3132333435?

Лучший результат, который я могу получить, составляет < 3132333435 > , путем записи строки NSData.

Я могу получить желаемый результат, используя эту ссылку: Есть ли у swift протокол для записи потока байтов?, но я не могу добавить данные в файл, который у меня есть создано.

Ответ 1

Я бы предложил использовать NSFileHandle.

Я протестировал вот так. Я начал с файла ~/Desktop/test.txt, содержащего слово "тестирование". Затем я запустил этот код:

    let s = "12345"
    let d = s.dataUsingEncoding(NSASCIIStringEncoding)!
    let path = ("~/Desktop/test.txt" as NSString).stringByExpandingTildeInPath
    if let fh = NSFileHandle(forWritingAtPath: path) {
        fh.seekToEndOfFile()
        fh.writeData(d)
        fh.closeFile()
    }

В результате файл содержал

testing12345

Хэш-дамп показал, что базовые байты:

74 65 73 74 69 6E 67 31 32 33 34 35

Я считаю, что вы сказали, что хотите достичь.

Кроме того, еще один номер:

Лучший результат, который я могу получить, - <3132333435>

Звучит так, как будто проблема заключается в том, что вы не знаете, как читать вывод консоли. < и > на самом деле не находятся в файле; они являются лишь частью консольного представления данных. Было бы лучше использовать BBEdit/TextWrangler или выделенный гексагон-дампер, чтобы увидеть фактический байт файла.

Ответ 2

В основном проблема заключается в том, чтобы ваши данные были правильно преобразованы в указатель, чтобы получить его до NSOutputStream.write. Следующее расширение должно делать то, что вам нужно:

extension NSOutputStream {
    enum WriteErrors : ErrorType {
        case UTF8ConversionFailed
    }

    func write(string:String) throws -> Int {
        guard let data = string.dataUsingEncoding(NSUTF8StringEncoding) else {
            throw WriteErrors.UTF8ConversionFailed
        }

        return write(UnsafePointer(data.bytes), maxLength: data.length)
    }

    func write(var i:Int32) throws -> Int {
        return withUnsafePointer(&i) {
            self.write(UnsafePointer($0), maxLength: sizeof(Int32))
        }
    }
}

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