Python file does not exist exception - python

I am trying to open a file and read from it and if the file is not there, I catch the exception and throw an error to stderr. The code that I have:
for x in l:
try:
f = open(x,'r')
except IOError:
print >> sys.stderr, "No such file" , x
but nothing is being printed to stderr, does open create a new file if the file name doesn't exist or is the problem somewhere else?

Try this:
from __future__ import print_statement
import sys
if os.path.exists(x):
with open(x, 'r') as f:
# Do Stuff with file
else:
print("No such file '{}'".format(x), file=sys.stderr)
The goal here is to be as clear as possible about what is happening. We first check if the file exists by calling os.path.exists(x). This returns True or False, allowing us to simply use it in an if statement.
From there you can open the file for reading, or handle exiting as you like. Using the Python3 style print function allows you to explicitly declare where your output goes, in this case to stderr.

You have the os.path.exists function:
import os.path
os.path.exists(file_path)
returns bool

It works for me. Why can't you make use of os.path.exists()
for x in l:
if not os.path.exists(x):
print >> sys.stderr , "No such file", x

Related

Should I close a file with file.close() when there is a FileNotFoundError exception?

I'm trying to open a file in python and print a message when the file doesn't exist. But I'm confused whether to close the file or not when the exception happens.
try:
file = open(sys.argv[1], "r")
file.close() # should I do this?
except OSError:
print(f"{sys.argv[1]} file not found.")
A simpler method of checking if a file exists:
import os
if not os.path.exists(sys.argv[1]):
print(f"{sys.argv[1]} file not found.")
But to answer your question, the ```file.close()`` happens only when the file exists and you successfully open the file. Not when the exception occurs.
Edit:
As pointed out by #ekhumoro, the above has a race condition (when other processes access that file). If no other process accesses that file, then the above code works.
Solution is as #ekhumoro pointed out is to use your original try/except method.

exception stop read files python

I'm trying to control exceptions when reading files, but I have a problem. I'm new to Python, and I am not yet able to control how I can catch an exception and still continue reading text from the files I am accessing. This is my code:
import errno
import sys
class Read:
#FIXME do immutables this 2 const
ROUTE = "d:\Profiles\user\Desktop\\"
EXT = ".txt"
def setFileReaded(self, fileToRead):
content = ""
try:
infile = open(self.ROUTE+fileToRead+self.EXT)
except FileNotFoundError as error:
if error.errno == errno.ENOENT:
print ("File not found, please check the name and try again")
else:
raise
sys.exit()
with infile:
content = infile.read()
infile.close()
return content
And from another class I tell it:
read = Read()
print(read.setFileReaded("verbs"))
print(read.setFileReaded("object"))
print(read.setFileReaded("sites"))
print(read.setFileReaded("texts"))
Buy only print this one:
turn on
connect
plug
File not found, please check the name and try again
And no continue with the next files. How can the program still reading all files?
It's a little difficult to understand exactly what you're asking here, but I'll try and provide some pointers.
sys.exit() will terminate the Python script gracefully. In your code, this is called when the FileNotFoundError exception is caught. Nothing further will be ran after this, because your script will terminate. So none of the other files will be read.
Another thing to point out is that you close the file after reading it, which is not needed when you open it like this:
with open('myfile.txt') as f:
content = f.read()
The file will be closed automatically after the with block.

Subprocess error file

I'm using the python module subprocess to call a program and redirect the possible std error to a specific file with the following command:
with open("std.err","w") as err:
subprocess.call(["exec"],stderr=err)
I want that the "std.err" file is created only if there are errors, but using the command above if there are no errors the code will create an empty file.
How i can make python create a file only if it's not empty?
I can check after execution if the file is empty and in case remove it, but i was looking for a "cleaner" way.
You could use Popen, checking stderr:
from subprocess import Popen,PIPE
proc = Popen(["EXEC"], stderr=PIPE,stdout=PIPE,universal_newlines=True)
out, err = proc.communicate()
if err:
with open("std.err","w") as f:
f.write(err)
On a side note, if you care about the return code you should use check_call, you could combine it with a NamedTemporaryFile:
from tempfile import NamedTemporaryFile
from os import stat,remove
from shutil import move
try:
with NamedTemporaryFile(dir=".", delete=False) as err:
subprocess.check_call(["exec"], stderr=err)
except (subprocess.CalledProcessError,OSError) as e:
print(e)
if stat(err.name).st_size != 0:
move(err.name,"std.err")
else:
remove(err.name)
You can create your own context manager to handle the cleanup for you -- you can't really do what you're describing here, which boils down to asking how you can see into the future. Something like this (with better error handling, etc.):
import os
from contextlib import contextmanager
#contextmanager
def maybeFile(fileName):
# open the file
f = open(fileName, "w")
# yield the file to be used by the block of code inside the with statement
yield f
# the block is over, do our cleanup.
f.flush()
# if nothing was written, remember that we need to delete the file.
needsCleanup = f.tell() == 0
f.close()
if needsCleanup:
os.remove(fileName)
...and then something like:
with maybeFile("myFileName.txt") as f:
import random
if random.random() < 0.5:
f.write("There should be a file left behind!\n")
will either leave behind a file with a single line of text in it, or will leave nothing behind.

Python : Check file is locked

My goal is to know if a file is locked by another process or not, even if I don't have access to that file!
So to be more clear, let's say I'm opening the file using python's built-in open() with 'wb' switch (for writing). open() will throw IOError with errno 13 (EACCES) if:
the user does not have permission to the file or
the file is locked by another process
How can I detect case (2) here?
(My target platform is Windows)
You can use os.access for checking your access permission. If access permissions are good, then it has to be the second case.
As suggested in earlier comments, os.access does not return the correct result.
But I found another code online that does work. The trick is that it attempts to rename the file.
From: https://blogs.blumetech.com/blumetechs-tech-blog/2011/05/python-file-locking-in-windows.html
def isFileLocked(filePath):
'''
Checks to see if a file is locked. Performs three checks
1. Checks if the file even exists
2. Attempts to open the file for reading. This will determine if the file has a write lock.
Write locks occur when the file is being edited or copied to, e.g. a file copy destination
3. Attempts to rename the file. If this fails the file is open by some other process for reading. The
file can be read, but not written to or deleted.
#param filePath:
'''
if not (os.path.exists(filePath)):
return False
try:
f = open(filePath, 'r')
f.close()
except IOError:
return True
lockFile = filePath + ".lckchk"
if (os.path.exists(lockFile)):
os.remove(lockFile)
try:
os.rename(filePath, lockFile)
sleep(1)
os.rename(lockFile, filePath)
return False
except WindowsError:
return True
According to the docs:
errno.EACCES
Permission denied
errno.EBUSY
Device or resource busy
So just do this:
try:
fp = open("file")
except IOError as e:
print e.errno
print e
Figure out the errno code from there, and you're set.

how to direct output into a txt file in python in windows

import itertools
variations = itertools.product('abc', repeat=3)
for variations in variations:
variation_string = ""
for letter in variations:
variation_string += letter
print (variation_string)
How can I redirect output into a txt file (on windows platform)?
From the console you would write:
python script.py > out.txt
If you want to do it in Python then you would write:
with open('out.txt', 'w') as f:
f.write(something)
Obviously this is just a trivial example. You'd clearly do more inside the with block.
You may also redirect stdout to your file directly in your script as print writes by default to sys.stdout file handler. Python provides a simple way to to it:
import sys # Need to have acces to sys.stdout
fd = open('foo.txt','w') # open the result file in write mode
old_stdout = sys.stdout # store the default system handler to be able to restore it
sys.stdout = fd # Now your file is used by print as destination
print 'bar' # 'bar' is added to your file
sys.stdout=old_stdout # here we restore the default behavior
print 'foorbar' # this is printed on the console
fd.close() # to not forget to close your file
In window command prompt, this command will store output of program.py into file output.txt
python program.py > output.txt
If it were me, I would use David Heffernan's method above to write your variable to the text file (because other methods require the user to use a command prompt).
import itertools
file = open('out.txt', 'w')
variations = itertools.product('abc', repeat=3)
for variations in variations:
variation_string = ""
for letter in variations:
variation_string += letter
file.write(variation_string)
file.close()
you may use >>
log = open("test.log","w")
print >> log, variation_string
log.close()
Extension to David's answer
If you are using PyCharm,
Go to Run --> Edit Configurations --> Logs --> Check mark Save console
output to file --> Enter complete path --> Apply

Categories