如何在快捷的游乐场中阅读文件

时间:2014-06-16 14:23:30

标签: swift

我尝试使用带有以下

的Swift游乐场阅读文本文件
let dirs : String[]? =    NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) as? String[]

if (dirs != nil) {
    let directories:String[] = dirs!;
    let dir = directories[0]; //documents directory
    let path = dir.stringByAppendingPathComponent(file);

    //read
    let content = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: nil)
}

然而,这失败并没有错误。似乎第一行阻止操场输出

以下的任何内容

10 个答案:

答案 0 :(得分:59)

您还可以将文件放入游乐场的资源中。为此:使用CMD + 1显示Project Navigator。将文件拖放到资源文件夹中。然后阅读文件:

在XCode 6.4和Swift 1.2上:

var error: NSError?
let fileURL = NSBundle.mainBundle().URLForResource("Input", withExtension: "txt")
let content = String(contentsOfURL: fileURL!, encoding: NSUTF8StringEncoding, error: &error)

在XCode 7和Swift 2上:

let fileURL = NSBundle.mainBundle().URLForResource("Input", withExtension: "txt")
let content = try String(contentsOfURL: fileURL!, encoding: NSUTF8StringEncoding)

在XCode 8和Swift 3上:

let fileURL = Bundle.main.url(forResource: "Input", withExtension: "txt")
let content = try String(contentsOf: fileURL!, encoding: String.Encoding.utf8)

如果文件包含二进制数据,则可以使用NSData(contentsOfURL: fileURL!)Data(contentsOf: fileURL!)(对于Swift 3)。

答案 1 :(得分:34)

虽然提供了快速解决方案的答案,但还有更好的解决方案。

每次打开游乐场时,都会为其分配一个新容器。这意味着使用普通的目录结构,您每次都需要将所需的文件复制到新容器中。

相反,在容器内部有一个指向共享游乐场数据目录(/ Users / UserName / Documents / Shared Playground Data)的符号链接,该目录在重新打开操场时仍然存在,并且可以从多个游乐场进入。

您可以使用XCPlayground访问此共享文件夹。

import XCPlayground

let path = XCPlaygroundSharedDataDirectoryURL.appendingPathComponent("foo.txt")

官方文档可在此处找到:XCPlayground Module Reference

关于如何按操场组织此目录的帖子很简短:Swift, Playgrounds, and XCPlayground


更新:对于swift 4.2使用playgroundSharedDataDirectory。不需要进口任何东西。 看起来像:

let path = playgroundSharedDataDirectory.appendingPathComponent("file")

答案 2 :(得分:16)

1。访问位于Playground的Resources文件夹

中的文件

使用Swift 3,Bundle有一个名为url(forResource:withExtension:)的方法。 url(forResource:withExtension:)有以下声明:

func url(forResource name: String?, withExtension ext: String?) -> URL?
  

返回由指定名称和文件扩展名标识的资源的文件URL。

您可以使用url(forResource:withExtension:)来阅读位于iOS或Mac Playground的Resources文件夹中的json文件的内容:

import Foundation

do {
    guard let fileUrl = Bundle.main.url(forResource: "Data", withExtension: "json") else { fatalError() }
    let data = try Data(contentsOf: fileUrl)
    let json = try JSONSerialization.jsonObject(with: data, options: [])
    print(json)
} catch {
    print(error)
}    

您可以使用url(forResource:withExtension:)来阅读位于iOS或Mac Playground的Resources文件夹中的文本文件的内容:

import Foundation

do {
    guard let fileUrl = Bundle.main.url(forResource: "Text", withExtension: "txt") else { fatalError() }
    let text = try String(contentsOf: fileUrl, encoding: String.Encoding.utf8)
    print(text)
} catch {
    print(error)
}

作为let image = UIImage(named: "image")的替代方案,您可以使用url(forResource:withExtension:)来访问位于iOS Playground的Resources文件夹中的图片:

import UIKit

do {
    guard let fileUrl = Bundle.main.url(forResource: "Image", withExtension: "png") else { fatalError() }
    let data = try Data(contentsOf: fileUrl)
    let image = UIImage(data: data)
} catch {
    print(error)
}

2。访问位于计算机~/Documents/Shared Playground Data文件夹中的文件

使用Swift 3,PlaygroundSupport模块提供了一个名为playgroundSharedDataDirectory的全局常量。 playgroundSharedDataDirectory有以下声明:

let playgroundSharedDataDirectory: URL
  

包含所有游乐场之间共享数据的目录的路径。

您可以使用playgroundSharedDataDirectory从iOS或Mac Playground中读取位于计算机~/Documents/Shared Playground Data文件夹中的json文件的内容:

import Foundation
import PlaygroundSupport

do {
    let fileUrl = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("Data.json")        
    let data = try Data(contentsOf: fileUrl)
    let json = try JSONSerialization.jsonObject(with: data, options: [])
    print(json)
} catch {
    print(error)
}

您可以使用playgroundSharedDataDirectory从iOS或Mac Playground中读取位于计算机~/Documents/Shared Playground Data文件夹中的文本文件的内容:

import Foundation
import PlaygroundSupport

do {
    let fileUrl = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("Text.txt")
    let text = try String(contentsOf: fileUrl, encoding: String.Encoding.utf8)
    print(text)
} catch {
    print(error)
}

您可以使用playgroundSharedDataDirectory从iOS Playground访问位于计算机~/Documents/Shared Playground Data文件夹中的图片:

import UIKit
import PlaygroundSupport

do {
    let fileUrl = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("Image.png")
    let data = try Data(contentsOf: fileUrl)
    let image = UIImage(data: data)
} catch {
    print(error)
}

答案 3 :(得分:11)

Swift 3(Xcode 8)

以下代码适用于iOS和macOS游乐场。文本文件(本例中为“MyText.txt”)必须位于playground的Resources目录中。 (注意:您可能需要打开导航窗口才能查看游乐场的目录结构。)

import Foundation

if let fileURL = Bundle.main.url(forResource:"MyText", withExtension: "txt")
{
    do {
        let contents = try String(contentsOf: fileURL, encoding: String.Encoding.utf8)
        print(contents)
    } catch {
        print("Error: \(error.localizedDescription)")
    }
} else {
    print("No such file URL.")
}

答案 4 :(得分:5)

这对我有用。我唯一改变的是明确文件名(在你的例子中暗示) - 也许你在"文件"的屏幕外定义中有一个拼写错误。变量?

let dirs = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) as? [String]

let file = "trial.txt" // My change to your code - yours is presumably set off-screen
if let directories = dirs {
  let dir = directories[0]; //documents directory
  let path = dir.stringByAppendingPathComponent(file);

  //read
  let content = NSString(contentsOfFile: path, usedEncoding: nil, error: nil)
  // works...
}

更新Swift 4.2

正如@raistlin所指出的,现在这将是

let dirs = NSSearchPathForDirectoriesInDomains(
              FileManager.SearchPathDirectory.documentDirectory,
              FileManager.SearchPathDomainMask.userDomainMask,
              true)

或更简洁:

let dirs = NSSearchPathForDirectoriesInDomains(.documentDirectory,
                                .userDomainMask, true)

答案 5 :(得分:3)

  1. 选择.playground文件。

  2. 打开实用程序检查器,在操场上按opt-cmd-1打开文件检查器。你应该看到右边的游乐场。如果您没有选择它,请按cmd-1打开Project Navigator并单击playground文件。

  3. 在Playground Settings的“资源路径”下,选择“相对于游乐场”和平台作为OSX。

答案 6 :(得分:1)

对于Xcode 6.0.1的小牛队,您也可以使用iOS平台阅读。

import UIKit
let dirs : [String]? =    NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) as? [String]
let myDir = "/Shared Playground Data"

let file = "README.md" // My change to your code - yours is presumably set off-screen
if (dirs != nil) {
  let directories:[String] = dirs!;
  let dir = directories[0] + myDir; // iOS playground documents directory
  let path = dir.stringByAppendingPathComponent(file);

  //read
  let content = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: nil)
  // works...
  println(content!)
}

请记住,您需要在Documents目录中创建一个名为"Shared Playground Data"的目录。在我的情况下,我使用了这个命令:mkdir "/Users/joao_parana/Documents/Shared Playground Data"并将文件README.md

放在那里

答案 7 :(得分:1)

String.stringWithContentsOfFile已弃用,并且不再适用于Xcode 6.1.1

创建documentDirectoryUrl

let documentDirectoryUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first! as NSURL

要确保文件位于那里,您可以使用finder命令Go To Folder e复制粘贴打印的documentDirectoryUrl.path那里

println(documentDirectoryUrl.path!)
// should look like this: /Users/userName/Library/Containers/com.apple.dt.playground.stub.OSX.PLAYGROUNDFILENAME-5AF5B25D-D0D1-4B51-A297-00015EE97F13/Data/Documents

只需将文件名附加到文件夹url作为路径组件

let fileNameUrl = documentDirectoryUrl.URLByAppendingPathComponent("ReadMe.txt")
var fileOpenError:NSError?

在尝试打开文件之前检查文件是否存在

if NSFileManager.defaultManager().fileExistsAtPath(fileNameUrl.path!) {

    if let fileContent = String(contentsOfURL: fileNameUrl, encoding: NSUTF8StringEncoding, error: &fileOpenError) {
        println(fileContent)        // prints ReadMe.txt contents if successful
    } else {
        if let fileOpenError = fileOpenError {
            println(fileOpenError)  // Error Domain=NSCocoaErrorDomain Code=XXX "The file “ReadMe.txt” couldn’t be opened because...."
        }
    }
} else {
    println("file not found")
}

答案 8 :(得分:0)

我无法轻松地在操场上读取文件,最终只用Xcode创建了一个command line应用。这似乎对我非常有效。

答案 9 :(得分:0)

依赖“playgroundSharedDataDirectory”的其他答案对我不起作用,尤其是在使用 iOS 游乐场时。

let documentsDirectoryShareURL = PlaygroundSupport.playgroundSharedDataDirectory.absoluteURL
let fileManager = FileManager()
try? fileManager.copyItem(at: URL(fileURLWithPath: "/Users/rufus/Documents/Shared Playground Data/"), to: documentsDirectoryShareURL)
我现在只做上面的。我可以填充我的文档/共享文件夹,它只是手动自动复制到 Playgrounds 文档目录。

我的代码不会覆盖那里存在的文件。如果您需要查看文件时间戳,然后在必要时进行复制等,您可以增强它。