Site logo

File - Folder

How to check if a file is already open

The Adobe JavaScript documentation has the following warning around opening files:
NOTE: Be careful about opening a file more than once. The operating system usually permits you to do so, but if you start writing to the file using two different File objects, you can destroy your data.

To tell if a File object is already open we can use the tell() method
Retrieves the current position as a byte offset from the start of the file.
Returns a number, the position index.

For an open file It returns: 0 (for new or empty file), or any number. If the file is not open, it returns -1.

main();

function main() {
	var file = new File("~/Desktop/Log.txt");
	
	if (file.exists) {
		file.open("e");
		file.seek(0, 2);
	}
	else {
		file.open("w");
	}

	var tell = file.tell(); // 0 for new or empty file; any number for existing file
	file.write("Test"); 
	file.close();
	tell = file.tell(); // -1 the file is closed
}

How to get the cache folder for both mac and windows?

app.generalPreferences.temporaryFolder.parent

With my German InDesign 2020 on Windows 10 it returns:

~/AppData/Local/Adobe/InDesign/Version%2015.0/de_DE/Caches

How to get file extension in JS:

var myString = "this.is.my.file.txt"
alert(myString.substring(myString.lastIndexOf(".")+1))

Get the file path to a file located in the same folder as the active script:

var csvFileName = "Change fonts list.csv";

function GetCsv() {
	var scriptFile = GetActiveScript();
	var scriptFolderPath = decodeURI(scriptFile.path) + "/";
	var csvFilePath = scriptFolderPath + csvFileName;
	var csvFile = new File(csvFilePath);

	if (csvFile.exists) {
		return csvFile;
	}
	else {
		return null;
	}
}

How to preselect a folder
for choosing files

var sourceFolder = currentFolder.parent;
if (sourceFolder != null) {
	var sourceFolderPath = decodeURI(sourceFolder.absoluteURI) + "/";
	var sourceFiles = Folder(sourceFolderPath).openDlg("Pick source files", "All Files:*.*, Illustrator files:*.ai, Acrobat files:*.pdf", true);

for choosing a folder

var myFolderPath = "/C/Test/Processed";
var myFolder = new Folder(myFolderPath);
myFolder.selectDlg();

File path on Mac

Examples:

InDesign — excelFile.fsName
/Users/kas/Library/CloudStorage/Dropbox/Mac/Documents/dummy_books.xlsx
InDesign — excelFile.absoluteURI
~/Library/CloudStorage/Dropbox/Mac/Documents/dummy_books.xlsx

alias
"Macintosh HD:Users:kas:Library:CloudStorage:Dropbox:Mac:Documents:dummy_books.xlsx"

HFS
Macintosh HD:Users:kas:Library:CloudStorage:Dropbox:Mac:Documents:dummy_books.xlsx

POSIX
/Users/kas/Library/CloudStorage/Dropbox/Mac/Documents/dummy_books.xlsx

Finder
document file "dummy_books.xlsx" of folder "Documents" of folder "Mac" of folder "Dropbox" of folder "CloudStorage" of folder "Library" of folder "kas" of folder "Users" of disk "Macintosh HD"

Here is how to handle it:

set x to (path to desktop folder) as string
set posixPath to POSIX path of x
set ascriptPath to POSIX file posixPath

Pre (Illustrator) 2020, the file path property contained a ‘file’ value (an Apple event descriptor of typeFSRef). The Carbon File Manager (of which the FSRef type is part) has been deprecated since 10.8 and doesn’t work properly with APFS volumes; hence the update.

Unfortunately, 2020 has changed it from a ‘file’ value to a ‘text’ value (typically an Apple event descriptor of typeUnicodeText), and these two data types are not interchangeable in AppleScript, which means all existing scripts that use this property will break.

What 2020 should have changed it to is a ‘file’ value of typeFileURL, which is the modern successor to the old typeFSS/typeFSRef types. That is, use `[NSURL fileURLWithPath: posixPathString].absoluteString.UTF8String` (or its CoreFoundation equivalent) to convert the file path to a file URL, then pack that into a descriptor of typeFileURL. That will minimize/avoid breaking user scripts as AppleScript treats all ‘file’ types as interchangeable.

In addition, if the document has not yet been saved to disk, right now the result is a string containing a slash followed by the document name, e.g. "/Untitled-1", which is definitely a bug. Instead, it should return ‘missing value’ (an AEDesc of typeType with cMissingValue as its data).

If you search through the app’s dictionary you’ll find other properties and parameters that may also have changed; e.g. the `file path` property of the `placed item` class, the `action file path` of the `load action` command. You might want to write some tests to see if that’s the case.

Feel free to include the above information when filing a bug report with Adobe. No guarantees they’ll be able/willing to make a quick compatibility fix for 24.0.1, but even if they do decide to leave it as a POSIX path string they need to fix the result when no file exists.

Until/Unless this is fixed in AI, if you need to write portable scripts then this will work (assuming the file exists; if not, AI returns garbage anyway):

to normalizeFilePath(v) -- given POSIX path or file value, returns a file value
	if class of v is text then -- assume v is a POSIX path string
		if v does not start with "/" then -- sanity check
			error "Not a POSIX path string." number -1700 from v to «class furl»
		end if
		return POSIX file v
	else -- assume v is some type of 'file' value
		return v as «class furl»
	end if
end normalizeFilePath

tell application "Adobe InDesign 2024"
	set f to my normalizeFilePath(file path of document 1)
end tell
log f --> file "Macintosh HD:Users:kas:Desktop:test:"

 


ExtendScript Oddity with File/Folder on Mac OS X

Sort file names function for Mac (workaround for a Mac OSx bug)

See also Functions for File & Folder