在swift中对特定值进行拆分或分块NSData

Jee*_*eef 5 nsdata ios swift

我正在试图找出如何NSData在特定值上"chunk"a .

输入数据

7E 55 33 22 7E 7E 22 AE BC 7E 7E AA AA 00 20 00 22 53 25 A3 4E 7E

输出数据

返回一个由3个元素组成的数组,[NSData]其中元素为:

  • 55 33 22
  • 22 AE BC
  • AA AA 00 20 00 22 53 25 A3 4E

我在哪里

我知道我可以这样做:

var ptr = UnsafePointer<UInt8>(data.bytes)
var bytes = UnsafeBufferPointer<UInt8>(start: ptr, count: data.length)
Run Code Online (Sandbox Code Playgroud)

而且我想通过做类似的比较迭代:

bytes[1] == UInt8(0x7E)
Run Code Online (Sandbox Code Playgroud)

我想建立"范围",但我想知道是否有更好的方法来解决这个问题?

代码存根

private fund chunkMessage(data: NSData) -> [NSData] {
  var ptr = UnsafePointer<UInt8>(data.bytes)
  var bytes = UnsafeBufferPointer<UInt8>(start: ptr, count: data.length)
  var ret = []

 // DO SOME STUFF

  return ret as! [NSData];

}
Run Code Online (Sandbox Code Playgroud)

Pav*_*vic 8

你使用的基于 adan1985 的 Swift 3 解决方案

  let length = data.count
  let chunkSize = 500
  var offset = 0

  repeat {
    // get the length of the chunk
    let thisChunkSize = ((length - offset) > chunkSize) ? chunkSize : (length - offset);

    // get the chunk
    let chunk = data.subdata(in: offset..<offset + thisChunkSize )

    // -----------------------------------------------
    // do something with that chunk of data...
    // -----------------------------------------------

    // update the offset
    offset += thisChunkSize;

  } while (offset < length);
Run Code Online (Sandbox Code Playgroud)


小智 5

我遇到了类似的情况,但是我只是想按特定大小对数据进行分块,这就是我如何使其在Swift 2.0中工作的方式。假设“数据”的类型为NSData,并且已经填充了您要拆分的信息:

    let length = data.length
    let chunkSize = 1048576      // 1mb chunk sizes
    var offset = 0

    repeat {
        // get the length of the chunk
        let thisChunkSize = ((length - offset) > chunkSize) ? chunkSize : (length - offset);

        // get the chunk
        let chunk = data.subdataWithRange(NSMakeRange(offset, thisChunkSize))

        // -----------------------------------------------
        // do something with that chunk of data...
        // -----------------------------------------------

        // update the offset
        offset += thisChunkSize;

    } while (offset < length);
Run Code Online (Sandbox Code Playgroud)

希望对别人有帮助


Mar*_*n R 4

可能有很多可能的解决方案。一种直接的方式,使用 NSData方法,将是

func chunkMessage(data: NSData, var separator : UInt8) -> [NSData] {
    let sepdata = NSData(bytes: &separator, length: 1)
    var chunks : [NSData] = []

    // Find first occurrence of separator:
    var searchRange = NSMakeRange(0, data.length)
    var foundRange = data.rangeOfData(sepdata, options: nil, range: searchRange)
    while foundRange.location != NSNotFound {
        // Append chunk (if not empty):
        if foundRange.location > searchRange.location {
            chunks.append(data.subdataWithRange(NSMakeRange(searchRange.location, foundRange.location - searchRange.location)))
        }
        // Search next occurrence of separator:
        searchRange.location = foundRange.location + foundRange.length
        searchRange.length = data.length - searchRange.location
        foundRange = data.rangeOfData(sepdata, options: nil, range: searchRange)
    }
    // Check for final chunk:
    if searchRange.length > 0 {
         chunks.append(data.subdataWithRange(searchRange))
    }
    return chunks
}
Run Code Online (Sandbox Code Playgroud)

正如评论中已经建议的,您可以使用 Swift 数组。这是一个可能的实现:

func chunkMessage(data: NSData, separator : UInt8) -> [[UInt8]] {

    let bytes = UnsafeBufferPointer<UInt8>(start: UnsafePointer(data.bytes), count: data.length)

    // Positions of separator bytes:
    let positions = filter(enumerate(bytes), { $1 == separator } ).map( { $0.0 } )

    // Non-empty ranges between the separator bytes:
    let ranges = map(Zip2([-1] + positions, positions + [bytes.count])) {
        (from : Int, to : Int) -> (Int, Int) in
        (from + 1, to - from - 1)
        }.filter( { $1 > 0 } )

    // Byte chunks between the separator bytes:
    let chunks = map(ranges) {
        (start: Int, count : Int) -> [UInt8] in
        Array(UnsafeBufferPointer(start: bytes.baseAddress + start, count: count))
    }

    return chunks
}
Run Code Online (Sandbox Code Playgroud)

我留给你测试哪一个表现更好:)