Notifications
Clear all

[Closed] close <stream> not releasing the file?

I created a file like this

createFile "textFile.text"
stream = openFile "textFile.txt" mode:"r+"
-- I then printed some text
print "some text to" to:stream

-- I am now done
-- Later I read some text from said file and did the following
close stream
deleteFile "textFile.txt"

and I get undefined and it does not delete the file what am I doing wrong
I think I have the usage correct. but if i did it would work right? I tried supplying the entire path but that does not seem to work either.

again Thanks for any help

Lost…

8 Replies

try this:

stream = createFile "textFile.text"
-- I then printed some text
print "some text to" to:stream

-- I am now done
-- Later I read some text from said file and did the following
close stream
deleteFile "textFile.txt"

cheers,
o

Just to clarify Ofer’s solution (which is the Right Way to do it)

CreateFile() creates the file on disk and keeps it open. It returns a FileStream, but you never captured it in a variable, so you had no access to it.
Then you opened that same file once again as a second FileStream and when you closed it, only the second stream was closed, the initial stream opened by CreateFile() was still open and the deleteFile() failed.

1 Reply
(@bakerco)
Joined: 1 year ago

Posts: 0

@ofer_z

thanks for the help!!

Thanks for explaining I was just about ask that question I think I understand that alot better now.


ok so here is what I have as a learning script please crit and help me become more efficient. oh yea and next script I am going to do I will try my hardest not to ask questions and figure it out for myself

-- access windows Environment Vars
 fn getEnvironmentPaths =
 (
 -- create batch run in command line and close buffer
 batchStream = createFile "path.bat" 
 format "@echo off
 path \%sourcesdk\%;\%VProject\%;
 path >env.txt" to:batchStream
 close batchStream
 dosCommand "path.bat"
 
 -- collect array of paths and clean up files
 path_array = #()
 in_text = openfile "env.txt"
 skipToString in_text "="
 while not eof in_text do
 (
 str = readDelimitedString in_text ";"
 if str != "
" then append path_array str
 )
 close in_text
 deleteFile "path.bat"
 deleteFile "env.txt"
 path_array 
 )
 
 -- create .ini 
 iniPath = GetDir #maxroot + "sourcetools.ini"
 stream = createFile iniPath
 close stream
 
 -- capture Environment Vars
 env_paths = getEnvironmentPaths()
 sourceSDK = env_paths[1]
 vProject = env_paths[2]
 
 -- write defaults to .ini
 setINISetting iniPath "DEFAULT PREFERENCES" "VProject" vProject
 setINISetting iniPath "DEFAULT PREFERENCES" "ExportPath" sourceSDK

Again thanks for all the help!!
Lost…

Ok, here are some comments on efficiency:

*You don’t need the code above. The setIniSetting() method is so cool, it actually creates the file for you if it does not exist. So you can just define iniPath and go on setting values in it – the file will be created for you automagically.

*While it is technically OK, in practice it is a better idea to store INI files in the \Plugcfg folder instead of the Max root. Even Autodesk went away from writing the 3dsmax.ini and plugin.ini files in the root for Max 9 and moved them to a folder in the user’s data structure.

Instead of using

iniFile = GetDir #maxroot + “sourcetools.ini”

you should use

iniFile = GetDir #plugcfg + “\sourcetools.ini”
or
iniFile = GetDir #plugcfg + “/sourcetools.ini”

Note that GetDir #maxroot returns a path ending with a backslash, but most of the other GetDir results don’t, so it never hurts to prepend a slash or double-backslash to the file name. It is an inconsistency we have to live with…

iniFile = GetDir #maxroot
“C:\Program Files\Autodesk\3ds max 9” –notice the backslash?

iniFile = GetDir #plugcfg
“C:\Documents and Settings\bpetrov\Local Settings\Application Data\Autodesk\3dsmax\9 – 32bit\enu\plugcfg” –NO backslash!

Hope this helps.

1 Reply
(@bakerco)
Joined: 1 year ago

Posts: 0

Yes!! thanks a million that really does help alot.

Noticed you have some videos on the subject of MaxScript I am definately gonna have a look.

thanks again

Lost…

would this be the same for creating and closing bitmaps? a bit of an issue i have closing bitmaps, and 3d max tends to store them in memory

Not the same.

When you create a bitmapValue in memory using a bitmap() constructor, render(), renderMap() etc. and assign the value to a variable, the variable points at the memory where the bitmap is stored. If you don’t assign a .filename and call save() on the bitmap, simply setting the variable to undefined and calling gc light:true will purge the memory. (or you could just set to undefined and wait for the automatic garbage collection to clear the memory when needed). This is because the BitmapValue is not being referenced by any variables anymore and is considered garbage.

If you DO call save() on the bitmap, the bitmap will be considered open and will require a close() call before the memory can be reclaimed.

ok so the following code is fine then?

Part 1.


				--bake element
				myShadowMap = shadowsmap()
				myShadowMap.outputSzX = myShadowMap.outputSzY = mySize
				myShadowMap.fileType = myTempPath 
				myShadowMap.filterOn = true	
		
				--bake properties
				myObj.INodeBakeProperties.addBakeElement myShadowMap
				myObj.INodeBakeProperties.bakeChannel = 11
				myObj.INodeBakeProperties.bakeEnabled = on
				myObj.INodeBakeProperties.nDilations = 2
				myObj.INodeBakeProperties.flags = 1 --whats this?
				
				myTemp = render rendertype:#bakeSelected outputSize:[mySize,mySize] vfb:true superblack:true antiAliasing:false --double size for testing...
				undisplay myTemp
				close myTemp
				
				myObj.bakeEnabled = false
				myObj.removeAllBakeElements()
				
				myBitmap = openBitmap myTempPath
				close myBitmap

Parts 2 futher down, to clear the bitmaps from memory…


				--clear out old bitmap
				myBitmap = bitmap mySize mySize color:white
				deleteFile myPath
				deleteFile myTempPath 				
				gc()

part 3 rendering a second shadowmap


				freeSceneBitmaps()
				
				--bake properties
				myObj.INodeBakeProperties.addBakeElement myShadowMap
				myObj.INodeBakeProperties.bakeChannel = 10
				myObj.INodeBakeProperties.bakeEnabled = on
				myObj.INodeBakeProperties.nDilations = 2
				myObj.INodeBakeProperties.flags = 1 --whats this?
				
				myTemp = render rendertype:#bakeSelected outputSize:[mySize,mySize] vfb:true superblack:true antiAliasing:true antiAliasFilterSize:50 antiAliasFilter:(Soften())
				undisplay myTemp
				close myTemp
				
				myObj.bakeEnabled = false
				myObj.removeAllBakeElements()
				
				copyFile myTempPath myPath --make a copy of the file

And this part is where ive had problems, max would open an old bitmap that i previously rendered ontop of, my way around was to make a copy of the bitmap…


				--create copy close bitmap (the problem is here?! opens an old bitmap?!)
				myBitmapTemp = openBitmap myPath
				myBitmap2 = bitmap mySize mySize color:white filename:myPath
				copy myBitmapTemp myBitmap2
				close myBitmapTemp
				
				myBlackCoords = [(mySize - 6), 7]
				myWhiteCoords = [(mySize - 6), 1]
				for r = 1 to 6 do
				(
					setpixels myBitmap2 myBlackCoords #((color 0 0 0), (color 0 0 0), (color 0 0 0), (color 0 0 0), (color 0 0 0), (color 0 0 0))
					myBlackCoords += [0,1]
					setpixels myBitmap2 myWhiteCoords #((color 255 255 255), (color 255 255 255), (color 255 255 255), (color 255 255 255), (color 255 255 255), (color 255 255 255))
					myWhiteCoords += [0,1]
				)

				save myBitmap2 
				close myBitmap2