이 작업을 수행하는 방법에는 각각 장단점이있는 다양한 방법이 있습니다. 쉘 방법이 빠른있는 분에 , 하지만 항상 최신 정보를 반환하지 않습니다 . AppleScript의 Finder 인터페이스는 생각보다 느리지 않지만 캐시 된 파일 크기에 대해 실행 가능한 값만 반환하고 그렇지 않은 경우 나머지 값은 "missing value"를 반환합니다. 시스템 이벤트 는 일반적으로 검색시 빠르지 만 파일 속성에 액세스 할 때 속도가 느려지므로 선택한 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: