簡體   English   中英

在Yosemite上使用JavaScript for Automation列出文件夾中的所有文件

[英]Listing all the files in a folder using JavaScript for Automation on Yosemite

我正在嘗試將一些舊的Applescript移植到新的JavaScript語法中。

事情似乎非常直接,所以:

tell application "System Events" to keystroke "t" using command down

成為:

System = Application('System Events');
System.keystroke("t", {using: "command down"})

但是我不能為我的生活找出如何列出特定位置的文件。 在AppleScript中,要返回/usr目錄中的文件列表,您可以:

tell application "System Events" to set fileList to name of items in folder "/usr"
-- > {"bin", "include", "lib", "libexec", "local", "sbin", "share", "standalone", "X11"}

但是我不能為我的生活弄清楚如何在Javascript中做到這一點。

System = Application('System Events')
myPath = Path("/usr")

fileList = System.items(myPath) 
-- > message not understood

fileList = System.folder(myPath)
-- > message not understood

fileList = System.diskItems(myPath)
-- > []

fileList = System.diskItems({at:myPath)
-- > []

我也嘗試了很多其他組合,但沒有運氣。 有任何想法嗎?

就像Leopard的Scripting Bridge之前一樣,JXA故意打破各種在AppleScript中完美運行的東西。 以下是原始AppleScript命令到JXA語法的轉換:

//tell application "System Events" to name of items in folder "/usr"
Application('System Events').folders.byName('/usr').items.name()

AS版本運行完美,但JXA等效只是拋出一個完全沒有意義的Error -1700: Can't convert types.

如果您編寫diskItems而不是items JXA似乎確實有效:

Application('System Events').folders.byName('/usr').diskItems.name()
// --> ["bin", "lib", "libexec", "local", "sbin", "share", "standalone", "X11", "X11R6"]

這表明JXA沉迷於同樣的內部“聰明”,導致SB打破這么多的應用程序。 (請注意,我在早期的測試中發現了許多這樣的設計缺陷,但是一旦很明顯AS開發人員只關心強加他們自己的個人意識形態和對其他人的偏見,殘缺的能力和破壞的兼容性被詛咒就放棄了。)

為了比較,這里是JavaScriptOSA(JOSA)原型我幾個月前很快就為JXA開發人員的參考組合在一起(他們很快忽略了它,natch):

app('System Events').folders.named('/usr').items.name()
// -> ["bin", "lib", "libexec", "local", "sbin", "share", "standalone", "X11", "X11R6"]

(雖然沒有完全完成或測試,但JOSA仍然比JXA更好看,更好​​地記錄,甚至包括一個自動翻譯工具,用於將AS命令轉換為JS語法。不幸的是,因為Apple已經刪除或棄用了AEM,CM ,PM和OSA Carbon API,我不推薦它用於生產用途;它純粹用於比較目的。)

同理:

set myPath to POSIX file "/usr"
tell application "System Events" to name of every disk item of folder named myPath
--> {"bin", "lib", "libexec", "local", "sbin", "share", "standalone", "X11", "X11R6"}

myPath = Path('/usr')
Application('System Events').folders.byName(myPath).diskItems.name()
// Error -1728: Can't get object.

var myPath = Path('/usr')
app('System Events').folders.named(myPath).diskItems.name()
// --> ["bin", "lib", "libexec", "local", "sbin", "share", "standalone", "X11", "X11R6"]

您可以通過將Path對象轉換為字符串來解決該特定情況,並使用它:

myPath = Path('/usr')
Application('System Events').folders.byName(myPath.toString()).diskItems.name()

雖然這種解決方法在其他情況下不一定有用; 例如,它在Finder中失敗,因為Finder不理解POSIX樣式的路徑字符串,並且無法從JXA Path對象獲取HFS樣式的路徑字符串(Finder確實理解):

set myPath to POSIX file "/usr"
tell application "Finder" to name of every item of item myPath
--> {"X11", "X11R6", "bin", "lib", "libexec", "local", "sbin", "share", "standalone"}

myPath = Path('/usr')
Application('Finder').folders.byName(myPath.toString()).items.name()
// Error -1728: Can't get object.

它就這樣了。 (例如,嘗試測試JXA對范圍,過濾器,相對和插入參考形式的支持 ;它特別腐爛。)

"System Events"方法確實具有簡單性的優點,但事實證明使用$.NSFileManager (現在可直接用於腳本編寫)可以顯着提高性能。

在我的系統上,開始與之比較

var strPath = '/usr';

var appSys = Application('System Events'),
lstHarvest = appSys.folders.byName(strPath).diskItems.name();

幾千次迭代的快速測試表明,通過這種略微巴洛克式的方法,我們可以通過適度的40%加速它:

var strPath = '/usr';
var fm = $.NSFileManager.defaultManager,
    oURL = $.NSURL.fileURLWithPathIsDirectory(strPath, true),
    lstFiles = ObjC.unwrap(
        fm.contentsOfDirectoryAtURLIncludingPropertiesForKeysOptionsError(
            oURL, [], 1 << 2, null
        )
    ),
    lstHarvest = [];

lstFiles.forEach(function (oItem) {
    lstHarvest.push(
        ObjC.unwrap(oItem.path)
    );
});

而且相當簡單,超過300%:

var strPath = '/usr';
var fm = $.NSFileManager.defaultManager,
    lstFiles = ObjC.unwrap(
        fm.contentsOfDirectoryAtPathError(strPath, null)
    ),
    lstHarvest = [];

lstFiles.forEach(function (oItem) {
    lstHarvest.push(
        ObjC.unwrap(oItem)
    );
});

我可以這樣得到它

 foldersList =  foldersList =  System.folders.byName("usr").folders.name()

- > [“bin”,“lib”,“libexec”,“sbin”,“share”,“standalone”,“X11”]

甚至這個工作:

   foldersList =  System.folders.byName("/Users/USERName/Documents/").folders.name()

但我到目前為止無法獲得Path命令來處理除“打開”之外的任何事情

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM