Read/Wrte line from/to file.

Hello! I have this “handler for reading lines” already written:


set CR to (return as string)
-- is there an ASCII Character for 'new line' ? 'line feed' ? 

(* This handler reads line "line_to_read" from file "Path_to_file".
A line is considered if it ends in 'Carriage Return' .*)
to read_line(Path_to_file, line_to_read)
	set Prev_delim to AppleScript's text item delimiters
	set AppleScript's text item delimiters to CR -- this is what will now separate elements.
	set the_data to text items of (read Path_to_file from 1 to eof)
	try
		set The_Return to (item line_to_read of the_data)
	on error
		set The_Return to 0
	end try
	set AppleScript's text item delimiters to Prev_delim -- this MUST be executed, or else mayor crash in afterwards processes.
	return The_Return
end read_line

This one works ok as long one nows what kind of file one is reading.

I’d like one for “writing lines”. I started one with exactly the same code as above but changing the try a little, but realized some problems came up if the replacement line is shorter than the older one, and when I wanted to re-write the changed data to the file, some of the old data was left on the file (the last characters)


(* This handler should replace the line 'line' of a file (given it's path) 
with 'info'. Again, line is considered if it ends in 'Carriage Return' .*)
to write_line(Path_to_file, line, info)
	...
	try
		set (item line of data_as_list) to info
	on error err_msg
		set (item line of data_as_list) to ""
	end try
	my Save_Log(Path_to_file, data_as_list as string, 1)
	...
end write_line

where ‘Save_Log’ would be: (I’m just adding this one because ‘write_line’ uses it and because I’d like to now if I’m doing something terrible here I never noticed…)


(* This handler writes 'some_data' to a file (recieves it's path) starting
at 'where'. It does not care if it is overwriting text already written before. *)
on Save_Log(Path_to_file, some_data, where) -- 'where' would be where it will start writing from: eof, 1, 23, 50, -1. -123, etc.
	try
		try
			set where to (where as integer) -- could be 'eof', not a valid integer, but could be 'donkey' too.
			-- on error
			-- set where to eof -- (Should I? If it was 'donkey', no changes will be made to 'where', so nothing will happen and first 'try' will crash too.)
		end try
		set Path_to_file to Path_to_file as alias -- to prevent from creating a file (that should be taken care of somewhere else)
		open for access Path_to_file with write permission
		write some_data to Path_to_file starting at where
		close access Path_to_file
	on error
		try
			close access Path_to_file
		end try
	end try
end Save_Log

Thanks a lot.

BTW: if I saved a script as an app and never backed up. Can I somehow get the source code back? (Tried dropping app on AS, opening in many text editors, etc. no result). I did so accidentally on a script that I’ve working for months… darn. And what is the difference between an app, an app bundle, a ‘run only’ script and all the saving options in AS?

OK, thanks a lot again, hope to get goos news!!

Nikel

I’d use these two handlers:

read_line(alias "path:to:file.txt", 2)

to read_line(path_to_file, line_to_read)
	paragraph line_to_read of (read path_to_file)
end read_line
substitute_line(alias "path:to:file.txt", 2, "KAKAFUTIS")

to substitute_line(path_to_file, this_line, info)
	--> get contents of actual file
	set oldParagraphs to paragraphs of (read path_to_file)
	
	--> replace contents of old file with new contents
	set item this_line of oldParagraphs to info
	
	--> coerce list of paragraphs to text again
	set AppleScript's text item delimiters to return
	set newParagraphs to oldParagraphs as text
	set AppleScript's text item delimiters to {""}
	
	--> write new contents to file
	set fileRef to (open for access path_to_file with write permission)
	set eof of fileRef to 0 --> delete contents
	write newParagraphs to fileRef
	close access fileRef
end substitute_line

Running Jaguar (not time to install Panther), a compiled script is a compiled script (a chunk of text starting with “FasdUAS 1.101.10” ascii and ending “FADE DEAD” hex; in the data fork, if you saved as data fork; in the resource ‘scpt’ if you saved as a regular script). An app is a carbon application with the same code, thought to run such code (so, some additional resources, such as icons, executable bits, etc.). You can edit it dropping the app’s icon onto Script Editor’s own icon.

An app bundle (still not running Panther) may be similar to an AppleScript Studio app: an executable binary and a bunch of files, including a compiled script. Should be also editable.

A “run only” (script/app/whatever) is a script compiled specially, so you can’t edit it anymore.

Some more info here:
http://macscripter.net/faq/comments.php?id=134_0_10_10_C
http://macscripter.net/faq/comments.php?id=125_0_5_10_C
http://macscripter.net/faq/comments.php?id=70_0_10_20_C

Well jj, thank you. That ‘paragraph’ command makes it a lot easyer. And if I had known that ‘eof’ can be manipulated like that, then even my own handler would have worked. One more question though: if I wanted to delete only some text, could I write:


set eof of fileref to (eof - 5)
-- or similar ?

Regarding my saved script as app. I’m running 10.2.6 and I’m very sorry (for me actually) to say I saved it as run only, since I didn’t knew exactly how it worked and thought it would open in AS if I didn’t. Anyway, I’ll have to rewrite I guess… :cry:

Thanks for the help.

A similar code:

set eof of fileref to (get eof of fileref) - 5

Would delete the last 5 characters of the file. We could translate this line as “set the length of this pretty file to (its own length) minus five characters”.
To extract specific indexes from a text, you can read the file, manipulate the text, then write back the result:

set fileref to (open for access file "path:to:file" with write permission)
set oldContents to read fileref --> enclose text in a variable
set eof of fileref to 0 --> delete contents of file
set newContents to (text 1 thru 5 of oldContents) & (text 9 thru 17 of oldContents) --> ignore characters 6 thru 8
write newContents to fileref --> write final text back to file
close access fileref --> close access

Thanks jj, you’re always helping me. I appreciate it. I haven’t gotten to test your handlers (I’m taking finals at University) but they can’t be wrong. And I’m exploring Smile now. Looks pretty powerful, but kinda complicated. A bit mixed up. Those dialogs are the most interesting part, but they seem quite complicated to understand and I haven’t found examples yet… :?

Anyway, thanks a lot, ant until next time!!