File or directory doesn't exist - python

I'm trying to use the current date as the file's name, but it seems either this can't be done or I'm doing something wrong. I used a variable as a name for a file before, but this doesn't seem to work.
This is what I tried:
import time
d = time.strftime("%d/%m/%Y")
with open(d +".txt", "a+") as f:
f.write("")
This is just to see if it create the file. As you can see I tried with a+ because I read that creates the file if it doesn't exist and I still get the same error.

The problem is with how you're using the date:
d = time.strftime("%d/%m/%Y")
You can't have a / in a filename, because that's a directory instead. You haven't made the directory yet. Try using hyphens instead:
d = time.strftime("%d-%m-%Y")
You almost certainly don't want to make directories in the structure day/month/year, so I assume that's not what you were intending.

You are including directory separators (/) in your filename, and those directories are not created for you when you try to open a file. There is either no 26/ directory or no 26/02/ directory in your current working path.
You'll either have to create those directories by other means, or if you didn't mean for the day and month to be directories, change your slashes to a different separator character:
d = time.strftime("%d-%m-%Y")

Related

How to handle long path with spaces in Windows with Python

In the following code, I need to iterate through files in a directory with long names and spaces in paths.
def avg_dmg_acc(path):
for d in os.listdir(path):
sub_path = path + '/' + d
if os.path.isdir(sub_path):
if d.startswith('Front'):
for f in os.listdir(sub_path):
fpath = r"%s" % sub_path + '/' + f
print(fpath)
print(os.path.exists(fpath))
df = pd.read_csv(fpath)
Then I ran the function providing the argument path:
path = r"./Mid-Con Master dd3d5c56-581c-42e0-acde-04e7feed3bb8/620138 91852327-e08d-4ed1-9774-383c888cb04e/Power End 2d41ba63-dfb9-4984-a5a5-153997fea43a"
avg_dmg_acc(path)
However I am getting file not exist error:
File b'./Mid-Con Master dd3d5c56-581c-42e0-acde-04e7feed3bb8/620138 91852327-e08d-4ed1-9774-383c888cb04e/Power End 2d41ba63-dfb9-4984-a5a5-153997fea43a/Front c41f42ce-7158-4371-8cf6-82d1bcf04787/Damage Accumulation f907a97a-6d2d-40f6-ba02-0bc0599b773b.csv' does not exist
As you can see, I am already using r"path" since I read it somewhere it handles spaces in path. Also the path was constructed manually in this version, e.g. sub_path = path + '/' + d but I tried to use os.path.join(path, d) originally and it didn't work. I also tried Path from pathlib since it is the recommended way in Python 3 and still the same. At one point I tried to use os.path.abspath instead of the relative path I am using now with ./ but it still says file not exist.
Why is it not working? Is it because the path is too long or spaces are still not dealt with correctly?
It turns out it is the length of the path that is causing this problem. I tried to reduce the folder name of the lowest level one character at a time and got to the point where os.path.exists(fpath) changed from false to true. I think I will need to rename all the folder names before processing

How to open a specific path with open()?

I'm trying to build a file transfer system with python3 sockets. I have the connection and sending down but my issue right now is that the file being sent has to be in the same directory as the program, and when you receive the file, it just puts the file into the same directory as the program. How can I get a user to input the location of the file to be sent and select the location of the file to be sent to?
I assume you're opening files with:
open("filename","r")
If you do not provide an absolute path, the open function will always default to a relative path. So, if I wanted to open a file such as /mnt/storage/dnd/5th_edition.txt, I would have to use:
open("/mnt/storage/dnd/4p5_edition","r")
And if I wanted to copy this file to /mnt/storage/trash/ I would have to use the absolute path as well:
open("/mnt/storage/trash/4p5_edition","w")
If instead, I decided to use this:
open("mnt/storage/trash/4p5_edition","w")
Then I would get an IOError if there wasn't a directory named mnt with the directories storage/trash in my present folder. If those folders did exist in my present folder, then it would end up in /whatever/the/path/is/to/my/current/directory/mnt/storage/trash/4p5_edition, rather than /mnt/storage/trash/4p5_edition.
since you said that the file will be placed in the same path where the program is, the following code might work
import os
filename = "name.txt"
f = open(os.path.join(os.path.dirname(__file__),filename))
Its pretty simple just get the path from user
subpath = raw_input("File path = ")
print subpath
file=open(subpath+str(file_name),'w+')
file.write(content)
file.close()
I think thats all you need let me know if you need something else.
like you say, the file should be in the same folder of the project so you have to replace it, or to define a function that return the right file path into your open() function, It's a way that you can use to reduce the time of searching a solution to your problem brother.
It should be something like :
import os
filename = "the_full_path_of_the_fil/name.txt"
f = open(os.path.join(os.path.dirname(__file__),filename))
then you can use the value of the f variable as a path to the directory of where the file is in.

taking data from files which are in folder

How do I get the data from multiple txt files that placed in a specific folder. I started with this could not fix. It gives an error like 'No such file or directory: '.idea' (??)
(Let's say I have an A folder and in that, there are x.txt, y.txt, z.txt and so on. I am trying to get and print the information from all the files x,y,z)
def find_get(folder):
for file in os.listdir(folder):
f = open(file, 'r')
for data in open(file, 'r'):
print data
find_get('filex')
Thanks.
If you just want to print each line:
import glob
import os
def find_get(path):
for f in glob.glob(os.path.join(path,"*.txt")):
with open(os.path.join(path, f)) as data:
for line in data:
print(line)
glob will find only your .txt files in the specified path.
Your error comes from not joining the path to the filename, unless the file was in the same directory you were running the code from python would not be able to find the file without the full path. Another issue is you seem to have a directory .idea which would also give you an error when trying to open it as a file. This also presumes you actually have permissions to read the files in the directory.
If your files were larger I would avoid reading all into memory and/or storing the full content.
First of all make sure you add the folder name to the file name, so you can find the file relative to where the script is executed.
To do so you want to use os.path.join, which as it's name suggests - joins paths. So, using a generator:
def find_get(folder):
for filename in os.listdir(folder):
relative_file_path = os.path.join(folder, filename)
with open(relative_file_path) as f:
# read() gives the entire data from the file
yield f.read()
# this consumes the generator to a list
files_data = list(find_get('filex'))
See what we got in the list that consumed the generator:
print files_data
It may be more convenient to produce tuples which can be used to construct a dict:
def find_get(folder):
for filename in os.listdir(folder):
relative_file_path = os.path.join(folder, filename)
with open(relative_file_path) as f:
# read() gives the entire data from the file
yield (relative_file_path, f.read(), )
# this consumes the generator to a list
files_data = dict(find_get('filex'))
You will now have a mapping from the file's name to it's content.
Also, take a look at the answer by #Padraic Cunningham . He brought up the glob module which is suitable in this case.
The error you're facing is simple: listdir returns filenames, not full pathnames. To turn them into pathnames you can access from your current working directory, you have to join them to the directory path:
for filename in os.listdir(directory):
pathname = os.path.join(directory, filename)
with open(pathname) as f:
# do stuff
So, in your case, there's a file named .idea in the folder directory, but you're trying to open a file named .idea in the current working directory, and there is no such file.
There are at least four other potential problems with your code that you also need to think about and possibly fix after this one:
You don't handle errors. There are many very common reasons you may not be able to open and read a file--it may be a directory, you may not have read access, it may be exclusively locked, it may have been moved since your listdir, etc. And those aren't logic errors in your code or user errors in specifying the wrong directory, they're part of the normal flow of events, so your code should handle them, not just die. Which means you need a try statement.
You don't do anything with the files but print out every line. Basically, this is like running cat folder/* from the shell. Is that what you want? If not, you have to figure out what you want and write the corresponding code.
You open the same file twice in a row, without closing in between. At best this is wasteful, at worst it will mean your code doesn't run on any system where opens are exclusive by default. (Are there such systems? Unless you know the answer to that is "no", you should assume there are.)
You don't close your files. Sure, the garbage collector will get to them eventually--and if you're using CPython and know how it works, you can even prove the maximum number of open file handles that your code can accumulate is fixed and pretty small. But why rely on that? Just use a with statement, or call close.
However, none of those problems are related to your current error. So, while you have to fix them too, don't expect fixing one of them to make the first problem go away.
Full variant:
import os
def find_get(path):
files = {}
for file in os.listdir(path):
if os.path.isfile(os.path.join(path,file)):
with open(os.path.join(path,file), "r") as data:
files[file] = data.read()
return files
print(find_get("filex"))
Output:
{'1.txt': 'dsad', '2.txt': 'fsdfs'}
After the you could generate one file from that content, etc.
Key-thing:
os.listdir return a list of files without full path, so you need to concatenate initial path with fount item to operate.
there could be ideally used dicts :)
os.listdir return files and folders, so you need to check if list item is really file
You should check if the file is actually file and not a folder, since you can't open folders for reading. Also, you can't just open a relative path file, since it is under a folder, so you should get the correct path with os.path.join. Check below:
import os
def find_get(folder):
for file in os.listdir(folder):
if not os.path.isfile(file):
continue # skip other directories
f = open(os.path.join(folder, file), 'r')
for line in f:
print line

Create file in python dynamically

I know it's a noob question but I have some difficulties to make it works
def create(file):
f = open(file,'w')
it returns "IOError: [Errno 2] No such file or directory: "
If I do that it works of course:
file ="myfile"
f = open(file,'w')
But I can't figure out how to create my file from the function parameter
Sorry for the noob question, thanks in advance for your help.
when you pass the "http://somesite.com/" as file to your function python treats it as a directory structure.
As soon as python gets to "http:/" it presumes we have a directory. Using forward slashes in unix is not allowed and I imagine it is the same for windows.
To turn the name into something useable you can use some variation of urlparse.urlsplit:
import urlparse
import urlparse
def parse(f):
prse = urlparse.urlsplit(f)
return prse.netloc if f.startswith("http") else prse.path.split("/",1)[0]
Sites can look like paths to directories to the operating system. for instance: stackoverflow.com/something will be interpreted as a directory stackoverflow.com in which there is a file something.
You can see this when you use os.path.dirname:
>>> os.path.dirname('stackoverflow.com/something')
'stackoverflow.com'
If this is indeed the case, and you still want to proceed, you're passing a path to a location in a directory and not just a file name.
You have to make sure the directory stackoverflow.com exists first:
file_path = 'stackoverflow.com/something'
dirname = os.path.dirname(file_path)
if not os.path.exists(dirname):
# if stackoverflow.com directory does not exist it will be created
os.makedirs(dirname)
# .. carry on to open file_path and use it.
Watch out from http:// and the likes and consider using a real url parser.
tip: file is already defined in python, you shouldn't override it by using it to name a variable.
Editing:
def create(file):
f = open(file,'w')
f.close()
If you call this function using:
create('myfile.txt')
It will create a file named myfile.txt in whatever directory the code is being run from. Note that you are passing in a string not an object.
Since I now see you are passing in a string similar to http://www.google.com, you are trying to create a file named www.google.com in the http: folder. You are going to have to truncate or change the / since Windows files cannot contain that character in their names.
We'll use everything after the last / in this example:
def create(filename):
filename = re.sub(r'.*//*', '', filename)
f = open(filename, 'w')
f.close()
So calling: create('www.google.com/morestuff/things') will create a file called things

Rename files using python

I want to rename a file from say {file1} to {file2}. I read about os.rename(file1,file2) in python and is able to do so.
I succeeded only when the the file is placed in the same folder as python script, so I want to ask how can we rename files of other folders i.e. different folder than the one in which python script is placed.
Just use the full path, instead of the relative path:
oldFile = 'C:\\folder\\subfolder\\inFile.txt'
newFile = 'C:\\foo\\bar\\somewhere\\other\\outFile.txt'
os.rename(oldFile, newFile)
To get the double-slash behavior, you can do the following
import os
oldFile = r'C:\folder\subfolder\inFile.txt' # note the r character for raw string
os.path.normpath(oldFile)
Output
'C:\\folder\\subfolder\\inFile.txt'
As others have noted, you need to use full path.
On the other note, take a look at shutil.move documentation, it can also be used for renaming.

Categories