When to close a file? - file-io

Is necessary to close a file when you only want create it? I'm supposed that it's only necessary in case of reading or writing.
_, err := os.OpenFile(name, os.O_CREATE, 0640)

Will it work? Yes. The file will be created.
Should you do it? No. It is a bad idea in general even though you can get away with it sometimes.
Opening a file allocates resources like a file handle to your process. You should close it to free those resources. Otherwise they will be unavailable until the process dies.

When you create the file you also open it, so you should close it.

Related

FTP Server Download Returns blank files

We have a process in place built on Excel VBA that uploads a file to FTP Server. On the other side, our client downloads it. Very randomly, they complain that the file they received is blank (the file name is the same though). We then check at our end and see that the file that was uploaded was never blank. So here comes the problem: we're always arguing whether it was our error or theirs.
I figured that there might be a couple of reasons behind it but I have a few questions to ask before coming to conclusions:
If, say, the file was never uploaded (a possibility), what happens when the client runs a download process at their end? Can that download process generate a blank file with the same name as our output file? It sounds impossible to me but since the client is following up on this issue, I have to ask this silly question.
How does the mechanism work - what are the steps that happen on FTP server the moment my process completes uploading the file? I sometimes see that as soon as I upload the file, a 0kb file is created and then a second later (or less) the file with right size appears? Could it be possible that their process is running right before this actual file creation?
Thank you in advance for your help!

Is it possible to create a file that is deleted when its (owning) process goes away?

I want to create a file on Mac OS X (10.6) that will be deleted automatically when my process goes away. Is this possible? It would be very handy for a file locking scheme I am implementing. Preferably as a Cocoa or Carbon call.
I know that on Windows, this is possible. It's a very neat feature, but I don't know if it is something that needs to be supported by the file system.
On win32 you can call CreateFile with FILE_FLAG_DELETE_ON_CLOSE.
In .net you can create a FileStream with FileOptions.DeleteOnClose as argument.
If you are writing your own program, you could use tmpfile() call.
It creates a temporary file that get removed automatically on program termination.
You could have your app delegate to create and delete the file via the NSApplicationDelegate, however, the file would remain there if the user force quits/shut down. If force quitting is not part of your concern, then this should work. If not, you can create a simple launch agent that checks if your process exists, and if not, delete the file.
You can register an atexit() handler to delete the file, but this will not necessarily be completely reliable, particularly if the program crashes.
If you want proper file locking, consider using flock(), although, it is cooperative.

Handling File Access when a file is in use

Since there's no way to reliably check if a file is in use before trying to access it, is it advisable to just make continuous attempts at moving/deleting/reading them until the action is succesful?
Hope this one helps... [it is in C#... and not the most elegant way of doing this, but still check it out] http://www.dotnetscraps.com/dotnetscraps/post/FileInUse.aspx
It depends on the language/operating system you're using. Most languages have some sort of method to check if file is available for opening; another thing you can do is to try to open the file and catch the exception if it is open. Finally, if you're solely intending to read from a file, you may be able to open it anyway.

Deleting image files within a directory (That might be used by another process)

How can i delete image files (ex *.gif) that might be in use, by another process in a directory?
You can't delete it, while another process is using it. This comes from low-level file handling of Windows. However you can play around with renaming the file or setting it to be deleted on next boot.
Process Explorer tool can help you finding which process is using the file and it can actually close the handle - given proper/administrative rights. So it is possible with API calls, but such forced close of file handle can result in unpredictable behavior of that process.
If you can't delete it, you might be able to rename it, but I'm not sure why some locked files can be renamed while others can't.
You can also schedule it to be deleted at next boot using MoveFileEx with a null destination and the MOVEFILE_DELAY_UNTIL_REBOOT flag:
http://msdn.microsoft.com/en-us/library/aa365240(VS.85).aspx
http://www.pinvoke.net/default.aspx/kernel32/MoveFileEx.html
http://www.pinvoke.net/default.aspx/Enums/MoveFileFlags.html
If you use My.Computer.FileSystem.DeleteFile, you can notify the user of what program has the file locked if another program is using the file. It can't be deleted if it's in use.
Try
My.Computer.FileSystem.DeleteFile("C:\Documents and Settings\anybody\Desktop\dummy.doc", _
FileIO.UIOption.AllDialogs, _
FileIO.RecycleOption.DeletePermanently, _
FileIO.UICancelOption.ThrowException)
Catch ex As System.IO.IOException
Console.WriteLine(ex.ToString())
End Try

Force a Samba process to close a file

Is there a way to force a Samba process to close a given file without killing it?
Samba opens a process for each client connection, and sometimes I see it holds open files far longer than needed. Usually i just kill the process, and the (windows) client will reopen it the next time it access the share; but sometimes it's actively reading other file for a long time, and i'd like to just 'kill' one file, and not the whole connection.
edit: I've tried the 'net rpc file close ', but doesn't seem to work. Anybody knows why?
edit: this is the best mention i've found of something similar. It seems to be a problem on the win32 client, something that microsoft servers have a workaround for; but Samba doesn't. I wish the net rpc file close <fileid> command worked, I'll keep trying to find out why. I'm accepting LuckyLindy's answer, even if it didn't solve the problem, because it's the only useful procedure in this case.
This happens all the time on our systems, particularly when connecting to Samba from a Win98 machine. We follow these steps to solve it (which are probably similar to yours):
See which computer is using the file (i.e. lsof|grep -i <file_name>)
Try to open that file from the offending computer, or see if a process is hiding in task manager that we can close
If no luck, have the user exit any important network programs
Kill the user's Samba process from linux (i.e. kill -9 <pid>)
I wish there was a better way!
I am creating a new answer, since my first answer really just contained more questions, and really was not a whole lot of help.
After doing a bit of searching, I have not been able to find any current open bugs for the latest version of Samba, please check out the Samba Bug Report website, and create a new bug. This is the simplest way to get someone to suggest ideas as to how to possibly fix it, and have developers look at the issue. LuckyLindy left a comment in my previous answer saying that this is the way it has been for 5 years now, well the project is Open Source the best way to fix something that is wrong by reporting it, and or providing patches.
I have also found one mailing list entry: Samba Open files, they suggest adding posix locking=no to the configuration file, as long as you don't also have the files handed out over NFS not locking the file should be okay, that is if the file is being held is locked.
If you wanted too, you could write a program that uses ptrace and attaches to the program, and it goes through and unlocks and closes all the files. However, be aware that this might possibly leave Samba in an unknown state, which can be more dangerous.
The work around that I have already mentioned is to periodically restart samba as a work around. I know it is not a solution but it might work temporarily.
This is probably answered here: How to close a file descriptor from another process in unix systems
At a guess, 'net rpc file close' probably doesn't work because the interprocess communication telling Samba to close the file winds up not being looked at until the file you want to close is done being read.
If there isn't an explicit option in samba, that would be impossible to externally close an open file descriptor with standard unix interfaces.
Generally speaking, you can't meddle with a process file descriptors from the outside. Yet as root you can of course do that as you seen in that phrack article from 1997: http://www.phrack.org/issues.html?issue=51&id=5#article - I wouldn't recommend doing that on a production system though...
The better question in this case would be why? Why do you want to close a file early? What purpose does it ultimately have to close the file? What are you attempting to accomplish?
Samba provides commands for viewing open files and closing them.
To list all open files:
net rpc file -U ADadmin%password
Replace ADadmin and password with the credentials of a Windows AD domain admin. This gives you a file id, username of who's got it open, lock status, and the filename. You'll frequently want to filter the results by piping them through grep.
Once you've found a file you want to close, copy its file id number and use this command:
net rpc file close fileid -U ADadmin%password
I needed to accomplish something like this, so that I could easily unmount devices I happened to be sharing. I wrote this quick bash script:
#!/bin/bash
PIDS_TO_CLOSE=$(smbstatus -L | tail -n-3 | grep "$1" | cut -d' ' -f1 - | sort -u | sed '/^$/$
for PID in $PIDS_TO_CLOSE; do
kill $PID
done
It takes a single argument, the paths to close:
smbclose /media/drive
Any path that matches that argument (by grep) is closed, so you should be pretty specific with it. (Only files open through samba are affected.) Obviously, you need root to close files opened by other users, but it works fine for files you have open. Note that as with any other force closing of a file, data corruption can occur. As long as the files are inactive, it should be fine though.
It's pretty ugly, but for my use-case (closing whole mount points) it works well enough.