Memory problem editing large PS files

my applescript to edit PS files works, but only for files up to 10 megs. anything over that, and a log file is created saying -108 OUT OF MEMORY. I did File → Get Info → Memory on the applescript droplet and maxed out it’s memory availability (as well, i maxed out the computer’s virtual memory capacity) yet it still won’t work. my script only looks for a line of text within the first 100 lines of each file, so I figure maybe there’s a way to get it to only edit the first portion of each file? As well, does this memory problem have anything to do with SimpleText (I maxed out it’s memory availability, too)?

btw, I have a 1.25GHZ Accelerated G4 with 256K RAM…didn’t figure I’d even have this problem.

thanks!

I’ve never messed with reading and writing specific parts of files so I hope someone else offers a solution. In the meantime, if you can provide more info, I’ll likely experiment to see what I can come up with (a few sample files would be welcome - you can send them to robj@woh.rr.com or provide download links). For those who might be able to help, the script in question can be found in this thread.

Are the files fairly consistent within the first 100 lines? If so, do you have a guess as to how many bytes are contained in the first 100 lines of the average file?

I doubt that SimpleText is causing problems since it isn’t involved in the script (as far as I know).

– Rob (making no promises) :wink:

Originally I though you could just read the first x bytes in, search and replace, then write that text back tot he file starting at 0 but the problem is that your new text is 1 character longer than the original text so this doesn’t work. So, here’s my next stab at it. Read the text in two chunks. Do your search and replace on the first, small chunk (since I think this is where you are having memory issues converting to lists & back to strings on such huge amounts of text), then write the whole thing back to the file. I also added a mechanism to have several search and replace routines if necessary. Hope this helps.

property search_strings : {"ORIGINX 0"} --add to these lists if there are more things to search & replace
property replace_strings : {"ORIGINX 32"}

property maximum_chunk : 512 -- this will read the first 512 characters of the file, if you need more, adjust as necessary.

on run
	open {choose file of type {"TEXT"}}
end run

on open the_files
	repeat with this_file in the_files
		try
			set the_content_start to read this_file from 1 to maximum_chunk
			set the_content_end to read this_file from (maximum_chunk + 1) to -1
			repeat with i from 1 to (count of search_strings)
				set the_content_start to my replace_chars(the_content_start, (item i of search_strings), (item i of replace_strings))
			end repeat
			my write_to_file((the_content_start & the_content_end), this_file, false)
		on error error_message number error_number
			set error_string to "Error: " & error_number & ". " & error_message
			activate
			beep 3
			set the_button to button returned of (display dialog error_string buttons {"Copy to Clipboard", "OK"} default button 1 with icon 0)
			if the_button = "Copy to Clipboard" then set the clipboard to error_string
			return
		end try
	end repeat
	activate
	beep
	display dialog "The operation is complete." buttons {"OK"} default button 1 with icon 1
end open

to replace_chars(this_text, search_string, replacement_string)
	set old_atid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to search_string
	set this_text to text items of this_text
	set AppleScript's text item delimiters to replacement_string
	set this_text to this_text as string
	set AppleScript's text item delimiters to old_atid
	return this_text
end replace_chars

to write_to_file(this_data, target_file, with_appending)
	try
		set target_file to target_file as text
		set open_target_file to open for access file target_file with write permission
		if with_appending = false then set eof of open_target_file to 0
		write this_data to open_target_file starting at eof
		close access open_target_file
		return true
	on error
		try
			close access file target_file
		end try
		return false
	end try
end write_to_file

Jon

Yep, that extra character is giving me fits, Jon. I don’t know if this will actually make a difference but here’s my attempt at reducing the script’s overhead. I’m working on a wild assumption so it may not help at all.

on open files_
	repeat with file_ in files_
		try
			my write_to_file(my replace_chars(read file_, "ORIGINX 0", "ORIGINX 32"), file_, false)
		on error error_message number error_number
			set this_error to "Error: " & error_number & ". " & ¬
				error_message & return
			set the log_file to ((path to desktop) as text) & "Script Error Log"
			my write_to_file(this_error, log_file, true)
			activate
			beep 3
			display dialog "An error report (Script Error Log) has been placed on the desktop." buttons ¬
				{"OK"} default button 1 with icon 0
		end try
	end repeat
	activate
	display dialog "The operation is complete." buttons ¬
		{"OK"} default button 1 with icon 1
end open

to replace_chars(this_text, search_string, replacement_string)
	set AppleScript's text item delimiters to the search_string
	set the item_list to every text item of this_text
	set AppleScript's text item delimiters to the replacement_string
	set this_text to the item_list as string
	set AppleScript's text item delimiters to ""
	return this_text
end replace_chars

to write_to_file(this_data, target_file, append_data)
	try
		set the target_file to the target_file as text
		set the open_target_file to ¬
			open for access file target_file with write permission
		if append_data is false then ¬
			set eof of the open_target_file to 0
		write this_data to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access file target_file
		end try
		return false
	end try
end write_to_file

– Rob

hey guys,

neither of the scripts worked…they both said “out of memory”.

i really only have to edit the first 50 or 60 lines of text for the file, so possibly jon’s script (without the repeat) would work? i’ve been trying to turn the repeat off in that script, but can’t figure it out (i’m a newbie). jon, would you be able to make it so that there’s no repeat, and the script only looks to edit the first 50 or 60 lines of each file?

much appreciated!

ryank
michelinesbury@hotmail.com

The second repeat in my script won’t add any overhead to the script, so don’t worry about, really. I have one last method to suggest but it’s ugly. If you were reading in a chunk from the beginning of a file and then doing a search and replace and the new text was less than or equal to the original chunk, you could just pad the beginning of new chunk with spaces so it was the same length as the original and then overwrite that new chunk to the beginning of the original file. Since this is not applicable (the new chunk turns out to be longer than the original), and reading most of the file into memory is causing problems, we have to be more creative. The solution is to read the original file completely in chunks, search and replace the chunks, and then write each chunk to the end of a new file until the original has been completely read, searched & replaced, and reconstructed. Here’s my code for this. It will rename the original file then rebuild it so you’ll be left with the original (“original_o.ext”) and the new file. Please let me know if this works (there’s probably a better way of doing this):

Jon

hey jon,
thanks a lot for your help (thanks, rob, too)!

i’m only going to be able to test the script this evening…i’m hoping it’ll work.

i feel stupid not knowing this code…i’m good with computers, i just never got around to learning applescript.

could you suggest any good websites to visit to learn how to write applescript??

thx again!

You are here. :wink:

MacScripter.net and Apple provide and link to many useful resources.

– Rob

i just thought of one more thing…

i have these files that i have convert every day (i have to change the filenames). they’re in sequence, but the names always have to be changed…

something like this:

seq001.vit1_1
seq002.vit1_1
seq003.vit3_1 ← the 1_1 can sometimes say 3_1
seq004.vit1_1
seq005.vit3_1
seq006.vit1_1

would I be able to change them to something like this (using a script)?

trt 01.gg0316
trt 02.gg0316
trt 03.gg0316
trt 04.gg0316
trt 05.gg0316
trt 06.gg0316

just hoping that there’s an easier way than renaming them all!

Jon,

I ran your latest script on a 20 MB test file and it produced the desired result where the previous scripts failed. Here are some stats regarding the test.

Computer: PowerBook G4 667, 512 MB RAM
Chunk Size: 1024
Time to complete: approximately 7 minutes

Success!

Ryan,

On the renaming issue, if you were running OS X, I’d urge you to consider Jon’s Name those Files!, a powerful file renaming utility for a reasonable price. Jon is a master when it comes to renaming files and he’s a heck of a developer in general! :slight_smile:

– Rob

Thanks, as always, for the plugs, Rob (a fine developer and gentlemen himself)–you make me blush.

Glad the script above worked for you, hope it does the same for Ryan.

Jon

hey guys,
the script works (i just didn’t cut and paste properly the first time)…
everything is fine, even for very large files. the only problem is that it takes forever with a huge group of files. since i know that the line that i have to change in every file exists within the first 100 lines of text of each file, is there a way for the script to only examine the first part of each file?

Thanks so much, guys! You’re true geniuses!