我正致力于在iOS Swift中为shapefile构建自定义文件开启工具(GIS格式,与此问题无关)。这些文件有一个100字节长的标题。我能够将其读入4字节数组,存储我想要的信息。我可以将这些数组转换为Swift类型Data
和NSData
,并有一些其他选项可用于转换它们(如Base64EncodedString
)。但是我无法将这些原始数组或数据或任何格式转换为有用的属性,例如Double
,Int
和String
。
import Foundation
struct ShapeReader {
var shapeFile = FileHandle(forReadingAtPath: "/Users/christopherjlowrie/Documents/Shapes/SF_Neighborhoods/Planning_Zones.shp")
var fileHeader: String{
let header = shapeFile?.readData(ofLength: 100)
let headerStream = InputStream(data: header!)
headerStream.open()
var buffer = [UInt8](repeating: 0, count: 4)
while (headerStream.hasBytesAvailable){
headerStream.read(&buffer, maxLength: buffer.count)
print(buffer)
let x = Data(buffer)
print(x)
}
return "A"
}
}
目前只返回A,因为测试原因我要它返回一个字符串
如何在Swift中打开文件并将其原始字节读入类型(Doubles
,Ints
,Strings
)?
答案 0 :(得分:10)
您可以按照以下方式执行此操作:
要从String,Int或Double转换为数据:
Xcode 9•Swift 4 //对于旧的Swift 3语法,请点击here
extension String {
var data: Data { return Data(utf8) }
}
extension Numeric {
var data: Data {
var source = self
// This will return 1 byte for 8-bit, 2 bytes for 16-bit, 4 bytes for 32-bit and 8 bytes for 64-bit binary integers. For floating point types it will return 4 bytes for single-precision, 8 bytes for double-precision and 16 bytes for extended precision.
return Data(bytes: &source, count: MemoryLayout<Self>.size)
}
}
要从Data转换回String,Int或Double:
Swift 4.2或更早版本
extension Data {
var integer: Int {
return withUnsafeBytes { $0.pointee }
}
var int32: Int32 {
return withUnsafeBytes { $0.pointee }
}
var float: Float {
return withUnsafeBytes { $0.pointee }
}
var float80: Float80 {
return withUnsafeBytes { $0.pointee }
}
var double: Double {
return withUnsafeBytes { $0.pointee }
}
var string: String? {
return String(data: self, encoding: .utf8)
}
}
编辑/更新Swift 5
extension Data {
var integer: Int {
return withUnsafeBytes { $0.load(as: Int.self) }
}
var int32: Int32 {
return withUnsafeBytes { $0.load(as: Int32.self) }
}
var float: Float {
return withUnsafeBytes { $0.load(as: Float.self) }
}
var float80: Float80 {
return withUnsafeBytes { $0.load(as: Float80.self) }
}
var double: Double {
return withUnsafeBytes { $0.load(as: Double.self) }
}
var string: String? {
return String(data: self, encoding: .utf8)
}
}
游乐场测试
let intData = 1_234_567_890_123_456_789.data // 8 bytes (64 bit Integer)
let dataToInt = intData.integer // 1234567890123456789
let intMinData = Int.min.data // 8 bytes (64 bit Integer)
let backToIntMin = intMinData.integer // -9223372036854775808
let intMaxData = Int.max.data // 8 bytes (64 bit Integer)
let backToIntMax = intMaxData.integer // 9223372036854775807
let myInt32Data = Int32(1_234_567_890).data // 4 bytes (32 bit Integer)
let backToInt32 = myInt32Data.int32 // 1234567890
let int32MinData = Int32.min.data // 4 bytes (32 bit Integer)
let backToInt32Min = int32MinData.int32 // -2147483648
let int32MaxData = Int32.max.data // 4 bytes (32 bit Integer)
let backToInt32Max = int32MaxData.int32 // 2147483647
let myFloatData = Float.pi.data // 4 bytes (32 bit single=precison FloatingPoint)
let backToFloat = myFloatData.float // 3.141593
backToFloat == .pi // true
let myDoubleData = Double.pi.data // 8 bytes (64 bit double-precision FloatingPoint)
let backToDouble = myDoubleData.double // 3.141592653589793
backToDouble == .pi // true
let myFloat80Data = Float80.pi.data // 16 bytes (128 bit extended-precision FloatingPoint)
let backToFloat80 = myFloat80Data.float80 // 3.141592653589793116
backToFloat80 == .pi // true
let myStringData = Data("Hello World !!!".data.prefix(4)) // 4 bytes
let backToString = myStringData.string // "Hell"