Как получить имя файла без расширения с локального URL-адреса файла в Swift [дубликат]

39
задан JohnK 3 November 2014 в 04:29
поделиться

17 ответов

Это с Swift 2, Xcode 7: если у вас есть имя файла с уже добавленным расширением, вы можете передать полное имя файла в качестве первого параметра и пустую строку в качестве второго параметра:

let soundURL = NSBundle.mainBundle()
    .URLForResource("soundfile.ext", withExtension: "")

Альтернативно, поскольку параметр расширения также работает.

Если у вас есть URL-адрес, и вы хотите получить имя самого файла по какой-либо причине, вы можете сделать это:

soundURL.URLByDeletingPathExtension?.lastPathComponent

Swift 4

let soundURL = NSBundle.mainBundle().URLForResource("soundfile.ext", withExtension: "")
soundURL.deletingPathExtension().lastPathComponent
44
ответ дан PeejWeej 27 August 2018 в 15:33
поделиться

В Swift 2.1 кажется, что текущий способ сделать это:

let filename = fileURL.URLByDeletingPathExtension?.lastPathComponent
let extension = fileURL.pathExtension
5
ответ дан Aneel 27 August 2018 в 15:33
поделиться

Очищенный ответ для Swift 4 с расширением от PHAsset:

import Photos

extension PHAsset {
    var originalFilename: String? {
        if #available(iOS 9.0, *),
            let resource = PHAssetResource.assetResources(for: self).first {
            return resource.originalFilename
        }

        return value(forKey: "filename") as? String
    }
}

Как отмечено в XCode, исходное имя файла - это имя актива в момент его создания или импорта .

0
ответ дан CodeBender 27 August 2018 в 15:33
поделиться

Лучший способ (или, по крайней мере, альтернатива в Swift 2.0) - использовать свойство String pathComponents. Это разделяет путь в массив строк. например

if let pathComponents = filePath.pathComponents {
    if let last = pathComponents.last {
        print(" The last component is \(last)") // This would be the extension
        // Getting the last but one component is a bit harder
        // Note the edge case of a string with no delimiters!
    }
}
// Otherwise you're out of luck, this wasn't a path name!
0
ответ дан Derek Knight 27 August 2018 в 15:33
поделиться

В Swift вы можете перейти на NSString, чтобы быстрее получить расширение:

extension String {
    func getPathExtension() -> String {
        return (self as NSString).pathExtension
    }
}
10
ответ дан djromero 27 August 2018 в 15:33
поделиться

Попробуйте это для простого решения Swift 4

extension String {
    func stripExtension(_ extensionSeperator: Character = ".") -> String {
        let selfReversed = self.reversed()
        guard let extensionPosition = selfReversed.index(of: extensionSeperator) else {  return self  }
        return String(self[..<self.index(before: (extensionPosition.base.samePosition(in: self)!))])
    }
}

print("hello.there.world".stripExtension())
// prints "hello.there"
2
ответ дан Eng Yew 27 August 2018 в 15:33
поделиться

Как указано в комментарии, вы можете использовать это.

let filename: NSString = "bottom_bar.png"
let pathExtention = filename.pathExtension
let pathPrefix = filename.stringByDeletingPathExtension
71
ответ дан gabbler 27 August 2018 в 15:33
поделиться

Возможно, я слишком поздно для этого, но решение, которое сработало для меня и считалось довольно простым, - это использовать #file компилятор. Вот пример, когда у меня есть класс FixtureManager, определенный в FixtureManager.swift внутри теста / Tests / MyProjectTests / Fixtures directory. This works both in Xcode and with swift test`

import Foundation

final class FixtureManager {

    static let fixturesDirectory = URL(fileURLWithPath: #file).deletingLastPathComponent()

    func loadFixture(in fixturePath: String) throws -> Data {
        return try Data(contentsOf: fixtureUrl(for: fixturePath))
    }

    func fixtureUrl(for fixturePath: String) -> URL {
        return FixtureManager.fixturesDirectory.appendingPathComponent(fixturePath)
    }

    func save<T: Encodable>(object: T, in fixturePath: String) throws {
        let data = try JSONEncoder().encode(object)
        try data.write(to: fixtureUrl(for: fixturePath))
    }

    func loadFixture<T: Decodable>(in fixturePath: String, as decodableType: T.Type) throws -> T {
        let data = try loadFixture(in: fixturePath)
        return try JSONDecoder().decode(decodableType, from: data)
    }

}
0
ответ дан GuidoMB 27 August 2018 в 15:33
поделиться

Решение Swift 4

Это решение будет работать для всех экземпляров и не зависит от ручного анализа строки.

let path = "/Some/Random/Path/To/This.Strange.File.txt"

let fileName = URL(fileURLWithPath: path).deletingPathExtension().lastPathComponent

Swift.print(fileName)

Результирующим выходом будет

This.Strange.File
20
ответ дан Lore 27 August 2018 в 15:33
поделиться

Строки в Свифте могут быть определенно сложными. Если вам нужен чистый метод Swift, вот как бы я это сделал:

  1. Используйте find , чтобы найти последнее вхождение "." в reverse строки
  2. Используйте advance , чтобы получить правильный индекс "." в исходной строке
  3. Используйте функцию String subscript, которая принимает IntervalType, чтобы получить строки
  4. Пакет все это в функции, которая возвращает необязательный кортеж имени и расширения

Что-то вроде этого:

func splitFilename(str: String) -> (name: String, ext: String)? {
    if let rDotIdx = find(reverse(str), ".") {
        let dotIdx = advance(str.endIndex, -rDotIdx)
        let fname = str[str.startIndex..<advance(dotIdx, -1)]
        let ext = str[dotIdx..<str.endIndex]
        return (fname, ext)
    }
    return nil
}

Который будет использоваться как:

let str = "/Users/me/Documents/Something.something/text.txt"
if let split = splitFilename(str) {
    println(split.name)
    println(split.ext)
}

Какие выходы:

/Users/me/Documents/Something.something/text
txt

Или, просто используйте имеющиеся методы NSString , такие как pathExtension и stringByDeletingPathExtension .

2
ответ дан Mike S 27 August 2018 в 15:33
поделиться

Они по какой-то причине избавились от pathExtension.

let str = "Hello/this/is/a/filepath/file.ext"
let l = str.componentsSeparatedByString("/")
let file = l.last?.componentsSeparatedByString(".")[0]
let ext = l.last?.componentsSeparatedByString(".")[1]
0
ответ дан Pescolly 27 August 2018 в 15:33
поделиться

Создает уникальный URL-адрес формы, включая две предыдущие папки

func createFileNameFromURL (colorUrl: URL) -> String {

    var arrayFolders = colorUrl.pathComponents

    // -3 because last element from url is "file name" and 2 previous are folders on server
    let indx = arrayFolders.count - 3
    var fileName = ""

    switch indx{
    case 0...:
        fileName = arrayFolders[indx] + arrayFolders[indx+1] + arrayFolders[indx+2]
    case -1:
        fileName = arrayFolders[indx+1] + arrayFolders[indx+2]
    case -2:
        fileName = arrayFolders[indx+2]
    default:
        break
    }


    return fileName
}
0
ответ дан Pvlub 27 August 2018 в 15:33
поделиться

В Swift 2.1 String.pathExtension больше не доступно. Вместо этого вам нужно определить его с помощью преобразования NSURL:

NSURL(fileURLWithPath: filePath).pathExtension
26
ответ дан Santanu Karar 27 August 2018 в 15:33
поделиться

Работает с Swift 3 / Swift 4. Добавляем эти поведения в класс String:

extension String {

    func fileName() -> String {
        return NSURL(fileURLWithPath: self).deletingPathExtension?.lastPathComponent ?? ""
    }

    func fileExtension() -> String {
        return NSURL(fileURLWithPath: self).pathExtension ?? ""
    }
}

Пример:

let file = "image.png"
let fileNameWithoutExtension = file.fileName()
let fileExtension = file.fileExtension()
35
ответ дан tesla 27 August 2018 в 15:33
поделиться

SWIFT 3.x Самое короткое родное решение

let fileName:NSString = "the_file_name.mp3"
let onlyName = fileName.deletingPathExtension
let onlyExt = fileName.pathExtension

Нет расширения или каких-либо дополнительных материалов (я тестировал на основе решения @gabbler для Swift 2)

3
ответ дан Trevor 27 August 2018 в 15:33
поделиться

Swift 3.0

 let sourcePath = NSURL(string: fnName)?.pathExtension
 let pathPrefix = fnName.replacingOccurrences(of: "." + sourcePath!, with: "")
1
ответ дан user3069232 27 August 2018 в 15:33
поделиться

Расширенное решение Swift 3.x:

extension String {
    func lastPathComponent(withExtension: Bool = true) -> String {
        let lpc = self.nsString.lastPathComponent
        return withExtension ? lpc : lpc.nsString.deletingPathExtension
    }

    var nsString: NSString {
         return NSString(string: self)
    }
}

let path = "/very/long/path/to/filename_v123.456.plist"
let filename = path.lastPathComponent(withExtension: false)

константа имени файла теперь содержит « filename_v123.456 "

1
ответ дан Роман Елизаров 27 August 2018 в 15:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: