Short Notes on Frontier, OSX and Long File Name

Frontier on OS X can't read or write files that have more 31 chars in their name. This is unfortunate, but until UserLand change this, here's are some simple workarounds. These are not ideal, not well tested, but hey, its a start.

The idea is to use the capacity of Frontier to host AppleScript scripts in its database. AppleScript doesn't have any problem to read/write files with long names. I could have used Perl (faster) instead of AppleScript, but I just wanted a very simple solution.


Writing files with long names

Suppose you want to loop in a Frontier table and write for each table that is a stringtype the content of the table with the name of the table in a folder.

If you have a table that have more than 31 chars, you are toast. The work around is to have an AppleScript like this one at, for example, workspace.longFileName.

*NOTE: Please check the html source to get the code, if it doesn't display well in your browser (for example in OmniWeb). You can also download the code (see the bottom of this page).


on longFileName (thisPath, s)

	set FH to (open for access thisPath with write permission)

	write s to FH

	close access FH

end

With this simple AppleScript, you can do now this for example.


local (item, itemName);

for item in @theTable {

	if typeof (item) == stringtype {

		itemName = nameOf (item^);

		if sizeOf (itemName) <= 31 { // legit for Frontier

			file.writeTextFile (f, item^, type: "TEXT", creator: "R*ch")}

		else { // use AppleScript instead

			workspace.longFileName (f, item^)}}}


Reading files with long names

This is more tricky. And more slow too.

When Frontier do a fileloop () in a folder, if the name of the file is longer than 31 chars, it will get for example, instead of a file named "members.getmembertablewithpassword" something like "members.getmembertablewi#162364". I didn't investigate much on this behavior, but it seems that you can count, in the case of long file name, to find a pound sign ('#') in the name of the file.

So here's what you can do. At workspace.getLongFileNameList put this AppleScript.


on getLongFileNameList (folderPath)

	set masterlist to {}

	set sublist to {}

	tell application "Finder"

		set fol to folderPath as alias

		set filelist to list folder fol

		repeat with filename in filelist

			if length of filename is greater than 31 then

				set longname to (contents of filename)

				set filepath to folderPath & (contents of filename)

				set FH to open for access (alias filepath)

				set s to read FH as string from 1 to (get eof (alias filepath))

				set sublist to {longname, s}

				set masterlist to masterlist & {sublist}

			end if

		end repeat

	end tell

	return masterlist

end

[ and some people have the guts to say that UserTalk is a language more complicated than AppleScript ]

The result of this AppleScript will produce a list of lists. Something like this:


{{"members.getmembertablewithpassword",

"#title \"mainResponder.members.getMemberTableWithPassword"\rSyntaxr\tmainResponder...}

Each list contained in the main list have 2 items, the first one is the name of the file that exceed 31 chars, the second one is the content of the file.

Now, here's what you can do if you want to read all the files in a folder that might contains files with long names.


local (folderpath = "Hard_Drive_Name:path:to:folder");

local (f, fname, sizeName, longnameExist = false);

fileloop (f in folderpath) {

	fname = file.filefrompath (f);

	sizeName = sizeOf (fname);

	if !(sizeName == 31 and fname contains '#') {

		msg (fname)} // read the file here

	else {

		longnameExist = true}};

if longnameExist {

	temp.longName = workspace.getLongFileNameList (folderpath)}

Be careful not to put workspace.getLongFileNameList in a loop, it only need to be called once for each folder.

Download workspace.longFileName
Download workspace.getLongFileNameList

* Thanks to Nicholas Riley who corrected some of my assumptions regarding the position of '#'. You can't take for granted that it will be at index 25 in the name of the file.