このタスクを実行するにはさまざまな方法があり、それぞれ長所と短所があります。シェル方法が急速あるっぽい、常に最新の情報を返しません。AppleScriptのFinderインターフェイスは思ったほど遅くはありませんが、キャッシュされているファイルサイズに対して実行可能な値のみを返します。 システムイベントは、取得時に高速ですが、ファイル属性にアクセスすると速度が低下するため、通常、選択したAppleScriptファイル管理アプリケーションです。また、Finderのように深いディレクトリ列挙を行うこともできません(ただし、手動で実装することはできます)。
Objective-Cスクリプトブリッジを使用して、超高速で、ディレクトリのサブフォルダーに完全に下降できるAppleScriptを作成することにしました。全体として、これは最善の方法ですが、教師が少し疑わしいという欠点があります。
# Loads the Foundation framework into the script so that we can access its
# methods and constants
use framework "Foundation"
# Declare properties that belong to the Foundation framework for easier
# referencing within the script
property this : a reference to current application
property NSArray : a reference to NSArray of this
property NSDirectoryEnumerationSkipsHiddenFiles : a reference to 4
property NSDirectoryEnumerationSkipsPackageDescendants : a reference to 2
property NSFileManager : a reference to NSFileManager of this
property NSSortDescriptor : a reference to NSSortDescriptor of this
property NSString : a reference to NSString of this
property NSURL : a reference to NSURL of this
property NSURLFileSizeKey : a reference to NSURLFileSizeKey of this
property NSURLNameKey : a reference to NSURLNameKey of this
property NSURLPathKey : a reference to NSURLPathKey of this
# Call the handler defined below. This is where the script does the actual
# retrieving of the files and filesizes
get my contentsOfDirectory:"~/Downloads"
# If we stopped the script at the line above, you'd see the entire contents of
# the directory subtree listed with file paths and filesizes, ordered in
# descending order by filesize. However, you only want the largest file, so
# we pick out the first item in the list.
return item 1 of the result
--------------------------------------------------------------------------------
# This is an AppleScript handler declaration
on contentsOfDirectory:dir
local dir # This tells the handler that the variable passed as the
# parameter is limited in scope to this handler
# Obtain a reference to the default file manager of the filesystem
set FileManager to NSFileManager's defaultManager()
# This is where retrieve the contents of the directory, recursing
# into any subfolders. The options declared tell the method to skip
# hidden files and not to look inside file packages, such as
# applications or library files. I've declared a list of keys that
# pre-fetch file attributes during this retrieval, making it faster
# to access their data later: filename, full path, and file size.
set fs to FileManager's enumeratorAtURL:(NSURL's ¬
fileURLWithPath:((NSString's stringWithString:dir)'s ¬
stringByStandardizingPath())) ¬
includingPropertiesForKeys:[¬
NSURLPathKey, ¬
NSURLNameKey, ¬
NSURLFileSizeKey] ¬
options:(NSDirectoryEnumerationSkipsHiddenFiles + ¬
NSDirectoryEnumerationSkipsPackageDescendants) ¬
errorHandler:(missing value)
# I created the script object just to speed up the process of
# appending new items to the empty list it contains.
script |files|
property list : {}
end script
# This is the repeat loop that we use to enumerate the contents
# of the directory tree that we retrieved above
repeat
# This allows us to access each item in the enumerator one
# by one.
set f to fs's nextObject()
# Once the list has been exhausted, the value returned above
# will be a "missing value", signifying that there are no more
# files to enumerate. Therefore, we can exit the loop.
if f = missing value then exit repeat
# Here, we retrieve the values of file attributes denoted
# by the keys I declared earlier. I'm picking out the path
# and the filesize as per your needs.
f's resourceValuesForKeys:[NSURLPathKey, NSURLFileSizeKey] ¬
|error|:(missing value)
# The above command returns a record containing the two
# file attributes. This record gets appended to the list
# stored in the script object above.
set end of list of |files| to the result as record
end repeat
# The list in the script object is an AppleScript list object. For
# the next part, I need a cocoa list object (NSArray).
set L to item 1 of (NSArray's arrayWithObject:(list of |files|))
# This defines a sort descriptor which is used to sort the array.
# I'm telling it to use the filesize key to sort the array by
# filesize, which will let us grab the largest file easily.
set descriptor to NSSortDescriptor's alloc()'s ¬
initWithKey:"NSURLFileSizeKey" ascending:no
# Sort the list.
L's sortedArrayUsingDescriptors:[descriptor]
# Return the result.
result as list
end contentsOfDirectory: