fReplaceSafe

AppleScript vanilla safe search/replace text in a file (data fork only)

OS version: OS X

(*
fReplaceSafe
Make search/replace operations in data fork of a file (eg, plain text file)

Parameters:
s: search term
r: replace term
f: file path, alias, posix path (input file to make search/replacements in, only data fork)
f2: file path, alias, posix path (output file)

You can also adjust the property "chunk" in the "nesteed" script object (the number of bytes to read every time)
The more ocurrences you expect to search/replace, the shortest number in property "chunk" (eg, 100 Kb).
If you are working in the classic environment, the limit is (aprox.): 25000 bytes for "chunk" and 4000 items for lists (eg, if you expect about 5000 search/replacements in 25000 bytes, it will crash).

Example:
fReplaceSafe("vaca", "perro", alias "path:to:inputFile.txt", "path:to:outputFile.txt")
*)

to fReplaceSafe(s, r, f, f2)
	local s, r, f, f2, fRef, rwd, currentPosition, currentChunk, msg, n
	script nesteed
		property chunk : 200 * 1024 --> 200 Kb, fine for typical operations
		to searchReplace(s, r, t)
			set oldTids to AppleScript's text item delimiters
			set AppleScript's text item delimiters to s
			set t to t's text items
			set AppleScript's text item delimiters to r
			set t to t as text
			set AppleScript's text item delimiters to oldTids
			t
		end searchReplace
	end script
	
	set f to f as Unicode text
	if f does not contain ":" then set f to POSIX file f as Unicode text
	
	set f to alias f --> make sure the file exists or throw error
	
	set f2 to f2 as Unicode text
	if f2 does not contain ":" then set f2 to POSIX file f2 as Unicode text
	
	--> open and empty output file
	set fRef to (open for access file f2 with write permission)
	set eof of fRef to 0
	
	try --> if anything is wrong, close output file
		
		set rwd to (count s) --> avoid missing parts
		set currentPosition to 1 --> position to start reading
		repeat
			--> pick a chunk of text
			try
				set currentChunk to (read f from currentPosition to (currentPosition + (nesteed's chunk)))
			on error
				try
					set currentChunk to (read f from currentPosition to -1)
				on error --> no more text
					exit repeat
				end try
			end try
			
			write (nesteed's searchReplace(s, r, currentChunk)) to fRef starting at eof
			set currentPosition to currentPosition + (nesteed's chunk) - rwd
		end repeat
		
		close access fRef
	on error msg number n
		try
			close access fRef
		end try
		error msg number n
	end try
end fReplaceSafe

property |version| : 1.0
property |from| : "jfileLib"
property author : "Pescados Software ยท PescadosWeb.com"
property |date| : date "martes, 27 julio 2004 00:00:00"
property license : "freeware, open-source"