ByteArrayOutputStream или эквивалент двоичной записи в Swift

#java #c# #swift

Вопрос:

Мне интересно, что эквивалентно Java java.io.ByteArrayOutputStream или C# BinaryWriter в Swift.

Возникли некоторые трудности в следующей static public class CustomArrayOutputStream extends java.io.ByteArrayOutputStream части. Интересно, как добиться тех же функций в Swift.

Swift-Код

 public class CustomSerializer {
   fileprivate var output: CustomArrayOutputStream

   func custom_bool(value: Bool) {
      output.write(value == true ? 1 : 0)
   }
}

// Having difficulties to convert it to Swift
static public class CustomArrayOutputStream : ?? {
    public func getBuffer() -> [UInt8] {
        return buf
    }
}
 

Java-код:

 public class CustomSerializer {
   protected CustomArrayOutputStream output;

   public void custom_bool(Boolean value) {
      output.write(value.booleanValue() ? 1: 0);
   }
}

static public class CustomArrayOutputStream extends java.io.ByteArrayOutputStream {
    public byte[] getBuffer() {
        return buf;
    }
}
 

или эквивалент C# BinaryWriter в Swift

 protected readonly BinaryWriter output;
 

Обновить:

Первый случай-добиться чего-то подобного

 var content:[UInt8] = output.getBuffer() 
var size: Int = output.size() 
 

но OutputStream не имеет getBuffer() и size() не существует.

или

второй вариант использования, не знаю, как преобразовать следующую Java в Swift

Ява

 public int getOffset() {
    return (int)output.BaseStream.Position;
}
 

Быстрый

 public func getOffset() -> Int {
    return output.???
}
 

Комментарии:

1. У тебя это не NSOutputStream работает?

2. Кроме того, какова ваша цель здесь? Если вы объясните, чего вы хотите достичь, возможно, мы сможем помочь вам с альтернативами.

3. @Cristik, пожалуйста, проверьте мой Update раздел.

4. Вы не дали много подробностей, дайте нам знать, какова ваша конечная цель, зачем вам нужны эти точные методы. В противном случае это проблема XY

Ответ №1:

Для методов, о которых вы просите, вы могли бы сделать очень простую реализацию с использованием OutputStream, что-то вроде этого; (помилуйте стиль кода, я сам довольно новичок в Swift)

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

 import Foundation

public class CustomSerializer {
    fileprivate var output = OutputStream.toMemory()

    init() {
        output.open()
    }

    deinit {
        output.close()
    }
    
    func custom_bool(value: Bool) -> Void {
        custom_write(value: UInt8(value ? 1 : 0))
    }

    func custom_int(value: Int32) -> Void {
        custom_write(value: value.bigEndian)
    }

    private func custom_write<T>(value: T) -> Void {
        var value = value
        let size = MemoryLayout.size(ofValue: value)
        withUnsafeBytes(of: amp;value) {
            ptr in
            output.write(ptr.baseAddress!.assumingMemoryBound(to: UInt8.self), maxLength: size)
        }
    }
 }

extension OutputStream {
    public func getBuffer() -> [UInt8] {
        return [UInt8](self.property(forKey: .dataWrittenToMemoryStreamKey) as! Data)
    }
    public func getOffset() -> Int {
        return (self.property(forKey: .dataWrittenToMemoryStreamKey) as! Data).count
    }
}

let test = CustomSerializer()
test.custom_bool(value: true)
test.custom_int(value: 4711)
print(test.output.getBuffer())  // [1, 0, 0, 18, 103]
print(test.output.getOffset()). // 5
 

Комментарии:

1. Классно! Мне интересно , почему мы используем bigEndian здесь vs littleEndian , а также следующая логика применима и ко всем другим типам данных , таким как UInt16, Int16, UInt64, Int64 и т. Д.? такие как func custom_int(value: Int64) { custom_write(value: value.bigEndian) }

2. Также еще один вопрос, как войти output.size() в Swift?