Unexpected behaviour when reading from file

When I read a text file to the end of the file I am getting an end of file error (error number -39). That is unexpected. I believe I should only get that error if I try and read past the end of the file. by default, AppleScript’s read command should read until the end of the file, and not beyond.

The following script (I think) should work correctly, but is unexpectedly throwing an error number -39.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set thePath to ((path to desktop folder) as text) & "test.txt"
set theFile to missing value
try
	set theFile to open for access file thePath with write permission
	set eof theFile to 0
	write "Success!" to theFile starting at 0
	close access theFile
	set theFile to missing value
	
	set theText to read file thePath from 0
	display dialog theText

on error errorMessage number errorNumber
	if theFile is not missing value then close access theFile
	display alert "Error number " & errorNumber message errorMessage
end try

If I specify the number of bytes to read, it works fine. But obviously I’d prefer to be able to read a file of arbitrary length as I won’t always know how many bytes are in the file.


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set thePath to ((path to desktop folder) as text) & "test.txt"
set theFile to missing value
try
	set theFile to open for access file thePath with write permission
	set eof theFile to 0
	write "Success!" to theFile starting at 0
	close access theFile
	set theFile to missing value
	
	set theText to read file thePath from 0 for 8
	display dialog theText
	
on error errorMessage number errorNumber
	if theFile is not missing value then close access theFile
	display alert "Error number " & errorNumber message errorMessage
end try

Any ideas?

I’m running macOS 11.2 on an M1 MacBook.

AppleScripter. The read from command is 1-based. So, change the 0 to a 1 and your script will work. A few comments FWIW:

  • The default for the read command is to read the entire file, making the from parameter unnecessary.

  • The AppleScript dictionary does not show a path to desktop folder command (although it works) but does show a path to desktop command.

  • “as text” is a parameter of path to desktop, and so the parentheses as shown in your script result in an unnecessary coercion.

Thanks, Peavine! Your script works as expected on my machine. Thanks too for the extra corrections/info. I do still have some questions though.

Hmm, you’re right, in that changing the 0 to a 1 in my script did work, but there does seem to be more to this. For what it’s worth, I’ve pretty much learned all I know about the AppleScript read/write commands from this old but useful post from Nigel Garvey: https://macscripter.net/viewtopic.php?id=24745.

In the following example, the script appears to work exactly the same whether I specify from 0, from 1 or omit the from parameter entirely.


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set thePath to (path to desktop as text) & "test.txt"
set theFile to missing value

try
	set theFile to open for access file thePath with write permission
	set eof theFile to 0
	set stuff to {msg:"Success!"}
	write stuff to theFile
	close access theFile
	set theFile to missing value
	
	set theText to msg of (read file thePath as record from 0)
	display dialog theText
	
on error errorMessage number errorNumber
	if theFile is not missing value then close access theFile
	display alert "Error number " & errorNumber message errorMessage
end try

If the above script is changed to read from some number larger than 1, it throws an error. So it seems that the parameter is having some effect, but that 1 and 0 are equivalents, or produce the equivalent result.

Are you able to explain what’s going on here?

I thought the default was to read from the position of the current file marker, and so it was useful to specify in case the file marker was somewhere other than the beginning of the file (e.g. if an error was thrown part way through the last time the file was read, or if the file had been read and the file marker was at the end of the file). Is that not the case?

Good to know. Thanks for pointing it out. I guess it’s easy to be sloppy when it works regardless.

I didn’t know that – thanks for explaining!

I’m sorry but I don’t have an explanation for that. The use of read’s “as” parameter is something Nigel has written about on a number of occasions but I can’t say I know much about its operation. Perhaps Nigel or another forum member will have some thoughts on this topic.

The default for the read-from command is shown in the AppleScript Language Guide as:

In your script the file access is closed before the read command, so the default would seem to be to read from the beginning of the file. It certainly doesn’t hurt anything to use the from parameter, though.

It seems, from keyword doesn’t work without specifying for keyword.

As I tested, this:

set theText to read file thePath from 0 for (get eof (file thePath))

is equivalent to:

set theText to read file thePath

So, it is better for OP to not use from keyword at all in this case. Well, really, if you want to know the intricacies of how AppleScript works, let a beginner write a script. :lol: No, I am completely honest, grateful to any novice user for lessons on what not to do. :slight_smile:

Today I learned from the OP 2 more things about AppleScript: 1) the read/write command’s from keyword does not work without the for keyword, 2) these keywords in conjunction work great with both file descriptors and file references.

Therefore, the following is quite realistic:


set theAlias to choose file

read theAlias from 0 to 5
read theAlias from 0 for 5

One important point Nigel made there is this:

The whole/text/string/Unicode text issue has largely disappeared since then – it was mostly a transition thing. But the big change since that article was written is that the default text encoding, MacRoman, has become almost extinct. Files are much more likely to be UTF-8 now.

If the text is “simple” ASCII, with no extended characters, the encoding is irrelevant – the first 127 code points are the same in ASCII, MacRoman and UTF-8 (and most other Roman encodings too). But unless you’re sure, leaving off the as parameter is asking for trouble.

Generally you should be reading and writing as «class utf8».

But once you do that, the from and for parameters are still byte counts, and no longer represent characters. If reading for results in splitting a multi-byte UTF-8 character, you will get an error.

So when writing, it’s fine to append UTF-8 text at eof. But when reading UTF text, it’s generally best to read the whole file at once, without from and for parameters.

Just as a resource to supplement Nigel’s 2007 post, the following thread includes a lot of great information on this topic (more write than read) with many code suggestions, discussions of error correction, and timing results.

https://macscripter.net/viewtopic.php?id=47286