Write to file
Last modification: Friday, May 01, 2009 11:58 pmWrites content to a file using AppleScript’s own ‘write’ command. Takes a single record as argument. Returns ‘true’, if write was successful, raises an AppleScript error, if unsuccessful.
Required parameters
__hfsPath (string)HFS style path to the file the content will be written to.
__content (string, list, etc.)
Content to write to the file.
Optional parameters
__overrideType (class)Class name for the data type to write __content as [e.g. string, list, etc.].
__atomically (boolean)
Write atomically. First writes data to temporary file, then switches original file with temporary file. Default: false
__appending (boolean)
Append __content to current file contents. Default: false
__appendWithNewline (boolean)
Appends __content with a preceding new line character if the file was not empty. Ignored if __appending is set to false. Default: false
__creatorType (string)
Four character code for creator type.
__fileType (string)
Four character code for file type.
__silenceErrors (boolean)
Do not raise AppleScript errors, fail silently. Default: false
__logFilePath (string)
HFS style path to log file. Overrides gLOG_FILE_PATH. If only a file name is specified the default Logs folder inside the user’s Library is used. Default: false
__debugMode (boolean)
Log debug messages. Requires __logFilePath to be set. Overrides gDEBUG_MODE. Default: false
Optional Globals
gLOG_FILE_PATH (string)If set, the value will be used for the path to the log file.
gDEBUG_MODE (boolean)
If set, the value will be used to enable debug messages.
gLAST_ERROR_MESSAGE (string)
Variable in which error message is stored.
gLAST_ERROR_NUMBER (integer)
Variable in which error number is stored.
Function Calls
-- Basic call, provide path and contentwriteToFile({__hfsPath:_filePath, __content:"Hello_World"})
-- Write atomically
writeToFile({__hfsPath:_filePath, __content:"Hello_World", __atomically:true})
-- Append to current content
writeToFile({__hfsPath:_filePath, __content:"Hello_World", __appending:true})
Implementation
on writeToFile(_args)try
set _functionName to "writeToFile"
-- Find out if debug mode needs to be enabled
try
set _debugMode to (__debugMode of _args)
on error
try
set _debugMode to gDEBUG
on error
set _debugMode to false
end try
end try
-- Set the path to the log file
try
set _logFilePath to (__logFilePath of _args)
if _logFilePath does not contain ":" then
set _logFilePath to (path to home folder as string) & "Library:Logs:" & _logFilePath
end if
on error
try
set _logFilePath to gLOG_FILE_PATH
on error
set _logFilePath to false
end try
end try
-- Debug message
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(): Checking arguments") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
-- Check arguments
try
set _silenceErrors to (__silenceErrors of _args)
on error
set _silenceErrors to false
end try
try
set _hfsPath to (__hfsPath of _args)
on error
set _hfsPath to ""
error "No path to write to specified."
end try
if class of _hfsPath is not in {string, text, Unicode text, «class utf8»} then error "Wrong data type for path to write to."
if _hfsPath is "" then error "Empty string for path to file to write to."
if _hfsPath does not contain ":" then error "No valid path to write to specified."
try
set _content to (__content of _args)
on error
error "No content to write specified."
end try
try
set _overrideType to (__overrideType of _args)
on error
set _overrideType to false
end try
if _overrideType is false then set _overrideType to class of _content
try
set _atomically to (__atomically of _args)
on error
set _atomically to false
end try
try
set _appending to (__appending of _args)
on error
set _appending to false
end try
if _appending then
try
set _appendWithNewline to (__appendWithNewline of _args)
on error
set _appendWithNewline to false
end try
end if
if _overrideType is list then set _appending to false
try
set _creatorType to (__creatorType of _args)
on error
set _creatorType to false
end try
try
set _fileType to (__fileType of _args)
on error
set _fileType to false
end try
set _originalContent to "ANFileHadNoContent"
if _atomically is false then
set _writeToPath to _hfsPath
else
-- Debug message
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Determining file name and directory") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
-- Determine file name and directory
-- Create file path for atomical writing
set _pDlmt to AppleScript's text item delimiters
try
set AppleScript's text item delimiters to ":"
set _fileName to text item -1 of _hfsPath
set _fileDirectory to text items 1 thru -2 of _hfsPath as string
set AppleScript's text item delimiters to ""
set _writeToPath to (_fileDirectory & ":" & (random number from 100000 to 999999) & _fileName) as string
set AppleScript's text item delimiters to _pDlmt
on error _eMessage number _eNumber
set AppleScript's text item delimiters to _pDlmt
error "Error while determining file name and directory: " & _eMessage number _eNumber
end try
-- Read original file content if necessary
if _appending then
try
tell application "System Events"
if (exists file _hfsPath) is false then error 1
end tell
set fileExists to true
on error
set fileExists to false
end try
if fileExists then
-- Debug message
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Reading current content") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
try
open for access file _hfsPath
on error _eMessage number _eNumber
error "Could not open file for reading: " & _eMessage number _eNumber
end try
try
set _originalContent to read file _hfsPath as _overrideType
on error _eMessage number _eNumber
try
close access file _hfsPath
end try
error "Could not read original file: " & _eMessage number _eNumber
end try
try
close access file _hfsPath
end try
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Current content: " & ((count of characters of _originalContent) as string) & " characters") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
end if -- fileExists
end if -- _appending
end if -- _atomically is false
-- Debug message
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Opening file with write permission") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
-- Open file to write to
try
open for access file _writeToPath with write permission
on error _eMessage number _eNumber
error "Could not open file with write permission: " & _eMessage number _eNumber
end try
-- Write to file
try
-- Debug message
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Writing to file") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
-- Determine end of file and data to write
if _appending is false then
set eof of file _writeToPath to 0
set _fileEnd to 0
set _writeData to _content
else
try
set _fileEnd to (get eof of file _writeToPath) + 1
on error
set _fileEnd to 0
end try
if _originalContent is not "ANFileHadNoContent" then
if _appendWithNewline then
set _writeData to _originalContent & return & _content
else
set _writeData to _originalContent & _content
end if
else
if _fileEnd > 1 then
if _appendWithNewline then
set _writeData to return & _content
else
set _writeData to _content
end if
else
set _writeData to _content
end if
end if
end if
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Content to write: " & ((count of characters of _writeData) as string) & " characters") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
write _writeData to file _writeToPath starting at _fileEnd as _overrideType
on error _eMessage number _eNumber
try
close access file _writeToPath
end try
error "Error while writing to file: " & _eMessage number _eNumber
end try
-- Debug message
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Closing file") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
try
close access file _writeToPath
end try
-- Option: Atomically - Delete original file and rename backup file
if _writeToPath is not _hfsPath then
-- Debug message
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Replacing original file with file written to") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
-- Try to delete the original file if it exists
try
tell application "System Events"
if (exists file _hfsPath) then
do shell script "rm -f " & quoted form of (POSIX path of _hfsPath)
end if
end tell
end try
-- Rename backup file
try
do shell script "mv " & quoted form of (POSIX path of _writeToPath) & " " & quoted form of (POSIX path of _hfsPath)
on error _eMessage number _eNumber
error "Error wile renaming backup file: " & _eMessage number _eNumber
end try
end if
if _creatorType is not false and _fileType is not false then
-- Debug message
if _debugMode and (_logFilePath is not false) then do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & "[Debug] " & _functionName & "(\"" & _hfsPath & "\"): Setting creator or type") & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
end if
try
if _creatorType is not false then
tell application "System Events" to set creator type of file _hfsPath to _creatorType
end if
end try
try
if _fileType is not false then
tell application "System Events" to set file type of file _hfsPath to _fileType
end if
end try
return true
on error _eMessage number _eNumber
set gLAST_ERROR_MESSAGE to _eMessage
set gLAST_ERROR_NUMBER to _eNumber
try
if _writeToPath is not _hfsPath then
tell application "System Events" to delete file _writeToPath
end if
end try
-- Log to file if a path has been specified
if _logFilePath is not false then
try
set _logMessage to "[Error] " & _functionName & "(\"" & _hfsPath & "\"): " & _eMessage & " (" & (_eNumber as string) & ")"
do shell script "echo " & quoted form of ((do shell script "date +\"%F %T %Z\"") & tab & _logMessage) & " >> " & quoted form of (POSIX path of _logFilePath) & " 2>/dev/null &"
end try
end if
-- Raise an error if silencing errors is disabled
if (_silenceErrors is false) then
set _eMessage to _functionName & "(\"" & _hfsPath & "\"): " & _eMessage & " (" & (_eNumber as string) & ")"
error _eMessage number _eNumber
end if
return false
end try
end writeToFile