2017-04-05 8 views
3

シェイプファイル用のiOS Swiftでカスタムファイルオープナーを作成しています(GIS形式、特にこの質問には関係ありません)。これらのファイルのヘッダーは100バイトです。私はこれを4バイト配列に読み込むことができます。これは、必要な情報を格納します。私はこれらの配列をSwiftタイプDataNSDataに変換し、それらを変換するためのいくつかの他のオプションを持っています(Base64EncodedStringなど)。しかし、私はこれらの生の配列またはデータまたはいずれかのフォーマットをDouble,Int、およびStringのような有用な属性に変換するのに問題があります。SwiftのDoubles、Ints、Stringsなどのデータにデータを変換するにはどうすればよいですか?

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" 
    } 
} 

これは、現在だけで、私はそれがどのように私は(StringsIntsDoubles)ファイルを開いて、タイプに彼らの生のバイトを読み取ることができる文字列に

を返すが午前の試験の理由であるため返します迅速?

答えて

5

あなたは次のようにそれを行うことができます。

を文字列、intまたはダブルからのデータに変換するには:

Xcodeの9•スウィフト4 //古いスウィフト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) 
    } 
} 
をクリックしてください

データを文字列、IntまたはDoubleに変換するには

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) ?? "" 
    } 
} 

遊び場試験


let intData = 1_234_567_890_123_456_789.data // 8 bytes (64 bit Integer) 
let dataToInt = intData.integer     // 123456789

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" 
+1

これは美しく働いた、ありがとう! –

+0

@ChrisLowrieあなたは歓迎です –

+0

フォローアップの質問:ダブルへの変換は意図したとおりに動作しません。 100を中心に2倍に戻るのではなく、戻り値は小さい(e-325のスケールで)。これはBig Endian/Little Endianと関係があります。私はこれを探し始めるかもしれない解決策や場所がありますか? –

関連する問題