web-dev-qa-db-ja.com

Swiftでテキストファイルを1行ずつ読みますか?

Swiftの学習を開始したばかりで、テキストファイルからコードを読み取ることができました。アプリにはテキストファイル全体の内容が表示されます。行ごとに表示し、その行を複数回呼び出すにはどうすればよいですか?

TextFile.txtには以下が含まれています。

  1. バナナ
  2. Apple
  3. イチゴ
  4. ブルーベリー
  5. 黒潮

以下は現在あるものです。

  if let path = NSBundle.mainBundle().pathForResource("TextFile", ofType: "txt"){
        var data = String(contentsOfFile:path, encoding: NSUTF8StringEncoding, error: nil)
            if let content = (data){
                TextView.text = content
    }

また、別の方法がある場合は、私に知らせてください。とても有難い

40
ScarletEnvy

Swift 3.0

if let path = Bundle.main.path(forResource: "TextFile", ofType: "txt") {
    do {
        let data = try String(contentsOfFile: path, encoding: .utf8)
        let myStrings = data.components(separatedBy: .newlines)
        TextView.text = myStrings.joined(separator: ", ")
    } catch {
        print(error)
    }
}

変数myStringsは、データの各行である必要があります。

使用されるコードは次のとおりです: iOS SDKで行ごとにファイルを読み取る Obj-Cで記述され、NSStringを使用

Swiftの以前のバージョンの編集履歴を確認します。

83
Caleb

Swift 2.0/Xcode 7.2の更新

    do {
        if let path = NSBundle.mainBundle().pathForResource("TextFile", ofType: "txt"){
            let data = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)

            let myStrings = data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
            print(myStrings)
        }
    } catch let err as NSError {
        //do sth with Error
        print(err)
    }

また、このコードは、(pathForResourceが使用されているため)プロジェクトフォルダー内にあるファイルを読み取ります。デバイスのドキュメントフォルダー

4
glace

Swift 5.0でこれを行うには、おそらく最も簡単で最も簡単な方法は次のようになります。

import Foundation

// Determine the file name
let filename = "main.Swift"

// Read the contents of the specified file
let contents = try! String(contentsOfFile: filename)

// Split the file into separate lines
let lines = contents.split(separator:"\n")

// Iterate over each line and print the line
for line in lines {
    print("\(line)")
}

注:これにより、ファイル全体がメモリに読み込まれ、メモリ内のファイルを反復処理して行が生成されます。

クレジットは次のようになります: https://wiki.codermerlin.com/mediawiki/index.php/Code_Snippet:_Print_a_File_Line-by-Line

2
NerdOfCode

これはきれいではありませんが、動作すると思います(Swift 5)。これは、反復とファイルの読み取りに基本的なPOSIX getlineコマンドを使用します。

typealias LineState = (
  // pointer to a C string representing a line
  linePtr:UnsafeMutablePointer<CChar>?,
  linecap:Int,
  filePtr:UnsafeMutablePointer<FILE>?
)

/// Returns a sequence which iterates through all lines of the the file at the URL.
///
/// - Parameter url: file URL of a file to read
/// - Returns: a Sequence which lazily iterates through lines of the file
///
/// - warning: the caller of this function **must** iterate through all lines of the file, since aborting iteration midway will leak memory and a file pointer
/// - precondition: the file must be UTF8-encoded (which includes, ASCII-encoded)
func lines(ofFile url:URL) -> UnfoldSequence<String,LineState>
{
  let initialState:LineState = (linePtr:nil, linecap:0, filePtr:fopen(fileURL.path,"r"))
  return sequence(state: initialState, next: { (state) -> String? in
    if getline(&state.linePtr, &state.linecap, state.filePtr) > 0,
      let theLine = state.linePtr  {
      return String.init(cString:theLine)
    }
    else {
      if let actualLine = state.linePtr  { free(actualLine) }
      fclose(state.filePtr)
      return nil
    }
  })
}

以下にその使用方法を示します。

for line in lines(ofFile:myFileURL) {
  print(line)
}
1
algal

おそらくファイル全体を一度に読みたいでしょう。きっととても小さいと思います。

ただし、結果の文字列を配列に分割し、配列のコンテンツをテーブルセルなどのさまざまなUI要素に分散したいとします。

簡単な例:

    var x: String = "abc\ndef"
    var y = x.componentsSeparatedByString("\n")
    // y is now a [String]: ["abc", "def"]
1
BaseZen