注意:如果您在序列化緩沖區中使用了 UTF8 編碼或者您有一系列 UTF8 字串,這只是一個問題。如果您在 23 位元組位元組陣列中有一個 UTF8 編碼字串,那么您顯然知道 UTF8 編碼的長度是 23 位元組或更少,并且您可能不關心末尾是否有額外的位元組。
我有一個帶有多個編碼的 UTF8 字串的資料物件,端到端。通過將 Data 物件傳遞給 String 建構式,我可以將第一個字串轉換為 String 物件。但是我想知道消耗了多少位元組,以便我可以轉換下一個 UTF 位元組塊。
例如:
let str = String(decoding:rawdata!, as: UTF8.self)
我想知道原始資料中消耗了多少位元組。
解決方案 1:將結果字串轉換回 UTF8View 并計算位元組數。
例如:
str.utf8.count
解決方案2:在UTF8編碼的字串之間插入一個帶有NUL字符的1位元組字串,并在將字串轉換回String物件后進行檢測。我假設這適用于 swift Strings,我的用例允許我編碼的字串永遠不會有那個值。
我更喜歡一種將 UTF8 陣列的初始部分轉換為 String 物件的方法,并且還可以獲取轉換所消耗的位元組數。
有沒有辦法做到這一點,或者更好的解決方法?
更新:#1 是我傾向于的解決方案。我不知道 String 實作是否重新計算了 UTF8 編碼以計算位元組數。在將 UTF8 轉換為 String 時,記住計數似乎更有效。
uj5u.com熱心網友回復:
Swift 字串可以包含NUL位元組(例如"Hello\u{0000}world!"是有效的String),因此假設您的字串以NUL位元組結尾,那么您的任何方法都不夠。
相反,您可能希望采用@Larme 作為評論發布的方法:首先拆分資料,然后從這些切片創建字串。
如果你的分隔符確實是一個NUL位元組,這可以很簡單
import Foundation
func decode(_ data: Data, separator: UInt8) -> [String] {
data.split(separator: separator).map { String(decoding: $0, as: UTF8.self) }
}
let data = Data("Hello, world!\u{00}Following string.\u{00}And another one!".utf8)
print(decode(data, separator: 0x00))
// => ["Hello, world!", "Following string.", "And another one!"]
split(separator:)這里的方法是Sequence.split(separator:maxSplits:omittingEmptySubsequences:),它需要一個分隔符Sequence.Element- 在這種情況下,是單個UInt8。因為omittingEmptySubsequences默認為true,即使您的分隔符是N NUL一行中的位元組,這也將起作用(因為您將獲得N - 1空分割,所有這些都將被丟棄)。
如果您的分隔符更復雜,則沒有類似的便捷方法,但您仍然可以使用Data方法來查找分隔符序列的實體并自己拆分它們:
import Foundation
func decode(_ data: Data, separator: String) -> [String] {
// `firstRange(of:)` below takes a type conforming to `DataProtocol`.
// `String.UTF8View` doesn't conform, but `Array` does. This copy should
// be cheap if the separator is small.
let separatorBytes = Array(separator.utf8)
var strings = [String]()
// Slicing the data will give cheap no-copy views into it.
// This first slice is the full data blob.
var slice = data[...]
// As long as there's an instance of `separator` in the data...
while let separatorRange = slice.firstRange(of: separatorBytes) {
// ... pull out all of the bytes before it into a String...
strings.append(String(decoding: slice[..<separatorRange.lowerBound], as: UTF8.self))
// ... and skip past the separator to keep looking for more.
slice = slice[separatorRange.upperBound...]
}
// If there are no separators, in the string, or the last string is not
// terminated with a separator itself, pull out the remaining contents.
if !slice.isEmpty {
strings.append(String(decoding: slice, as: UTF8.self))
}
return strings
}
let separator = "\u{00}\u{20}\u{00}"
let data = Data("Hello, world!\(separator)Following string.\(separator)And another one!".utf8)
print(decode(data, separator: separator))
// => ["Hello, world!", "Following string.", "And another one!"]
uj5u.com熱心網友回復:
試試這個解決方案
str.utf8.count
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/399295.html
