在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脚本桥一样,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语法的自动翻译工具。不幸的是,由于苹果已经将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命令处理任何事情,只能"打开"
- 如何在android中使用phonegap将文件从一个文件夹移动/复制到另一个文件夹
- 如何将乳胶配方奶粉图像保存到Asp.net中的文件夹中
- 展开和折叠文件夹
- 在ng重复循环中显示来自不同文件夹的图像
- 如何将所有JS文件连接到一个文件夹中
- 是否可以用JavaScript显示等效的文件夹对话框
- grunt上的压缩文件夹不起作用
- 如何使用javascript获取从指定文件夹创建的所有文件的名称、大小、类型和日期
- 将Windows文件路径组织到文件夹中
- 链接/按钮从子文件夹下载文件--浏览器只是浏览
- 在更改名称时,使用ajax jsp在下拉菜单中填充多个文件夹的数据
- 我应该将MVC视图特定的javascript文件放在哪个文件夹中
- 如何将JS文件从其他文件夹链接到页面
- 将文件从应用程序文件夹复制到JQM/Phonegap应用程序中的根文件夹
- 如何使用javascript创建新的文件夹/文件
- S3 循环访问存储桶/文件夹/文件
- 如何从javascript工作在c# .aspx文件,指向正确的文件夹/文件与href和src
- 上传文件夹&文件
- 使用Javascript返回文件夹+文件
- 获取当前目录中文件夹/文件的列表