I can write to a file in current directory.
I cannot write to a file in a subdirectory.
I checked online but the posts and previous questions didn't really help.
I have the code below, it should write to File.txt which is inside Subfolder. However, instead of this, I get a new File called "SubFolder\File.txt" in my current directory.
Any help?
PATH = os.getcwd()
PATH+= 'SubFolder\File.txt'
fileInput = open(PATH, "w")
fileOutput = open("SubFolder\File.txt", "w")
I expect a file in a subfolder.
I get a file with the desired path as a file name. Can you help? Thanks!
use double escape for file paths.
fileOutput = open("SubFolder\\File.txt", "w")
Opening a file for writing doesn't create any intervening subfolders that don't yet exist. You have to create them yourself first, using os.mkdir() (for one level) or os.makedirs() (for multiple levels).
Related
I don't know what's wrong here, all I'm trying to do is to open this file, but it says it can't find such a file or directory, however as I have highlighted on the side, the file is right there. I just want to open it. I have opened files before but never encountered this. I must have missed something, I checked online, and seems like my syntax is correct, but I don't know.
I get the same error when I try with "alphabetical_words" which is just a text file.
When open() function receives a relative path, it looks for that file relative to the current working directory. In other words: relative to the current directory from where the script is run. This can be any arbitrary location.
I guess what you want to do is look for alphabetical.csv file relative to the script location. To do that use the following formula:
from pathlib import Path
# Get directory of this script
THIS_DIR = Path(__file__).absolute().parent
# Get path of CSV file relative to the directory of this script
CSV_PATH = THIS_DIR.joinpath("alphabetical.csv")
# Open the CSV file using a with-block
with CSV_PATH.open(encoding="utf-8") as csvfile:
pass # Do stuff with opened file
You need to import csv. Then you can open the file as a csv file. For example,
with open ("alphabetical.csv", "r") as csvfile:
Then you can use the file.
Make sure the file is in your cwd.
this might be a silly question but I'm struggling a lot finding solution to it.
So I have a file in the given folder:
Output\20190101_0100\20190101_0100.csv
Now I want to zip the file and save it to same location. So here's my try:
zipfile.ZipFile('Output/20190101_0100/20190101_0100_11.zip', mode='w', compression=zipfile.ZIP_DEFLATED).write('Output/20190101_0100/20190101_0100_11.csv')
But it's making a folder insider zip folder and saving it, as shown below:
Output\20190101_0100\20190101_0100_11.zip\Output\20190101_0100\20190101_0100_11.csv
Can someone tell me how can I save my file directly in the same location or location mentioned below:
Output\20190101_0100\20190101_0100_11.zip\20190101_0100_11.csv
Rephrasing of question
The question is slightly confusing because Output\20190101_0100\20190101_0100_11.zip\Output\20190101_0100\20190101_0100_11.csv won't be a file, but rather Output\20190101_0100\20190101_0100_11.csv will be a file within the zip file Output\20190101_0100\20190101_0100_11.zip (if I am not mistaken)
Just to restate your problem (if I understood it correctly):
You have a file Output\20190101_0100\20190101_0100.csv (a file 20190101_0100.csv in the Output -> 20190101_0100 sub directory)
You want to create the zip file Output/20190101_0100/20190101_0100_11.zip (20190101_0100_11.zip in the Output -> 20190101_0100.zip directory)
You want to add the aforementioned CSV file Output\20190101_0100\20190101_0100.csv but without the leading path, i.e. as 20190101_0100_11.csv rather than Output\20190101_0100\20190101_0100.csv.
Or to not get confused with too many similar directories, let's simplify it as:
You have a file test.csv in the sub directory sub-folder
You want to create the zip file test.zip
You want to add the aforementioned CSV file test.csv but without the leading path, i.e. as test.csv rather than sub-folder/test.csv.
Answer
From the ZipFile.write documentation:
Write the file named filename to the archive, giving it the archive
name arcname (by default, this will be the same as filename, but
without a drive letter and with leading path separators removed).
That means that arcname will default to the passed in filename (it doesn't have a drive letter or leading path separator).
If you want to remove the sub folder part, just pass in arcname as well. e.g.:
import zipfile
with zipfile.ZipFile('path-to-zip/test.zip', 'w') as zf:
zf.write('sub-folder/test.csv', arcname='test.csv')
You could try using a raw path:
zipfile.ZipFile('Output/20190101_0100/20190101_0100_11.zip', mode='w', compression=zipfile.ZIP_DEFLATED).write(r'C:\...\Output\20190101_0100\20190101_0100_11.csv')
If I have a .py (called p.py) folder where I have my code and I want to open a file which is a .json (called j.json) file and I have opened it as a folder next to the p.py folder. I want to read from the j.json make it a dictionary. It does not seem to work with this :
import json
with open("j.json") as f:
data = json.load(f)
output: FileNotFoundError: [Errno 2] No such file or directory
What am I doing wrong?
If p.py and j.json are at the same level, we can directly quote it as its name instead of its absolute path:
Turn to file explorer, View -> Select File name extensions, to check if the name of j.json is right, or we can say, to check if j.json exists:
Try the full path directory instead of just your file name. But you should put an r before the string. E.g.
with open(r'path_to_file/j.json') as f:
data = json.load(f)
When you specify a path (that is not absolute) it is relative to the directory you are executing Python in
Let's say I'm in my Terminal at directory C:/Users/Mathias/Desktop and I execute the following code with Python
with open("veryimportant.json", "r") as file:
for line in file:
print(line)
"veryimportant.json" will be relative to my working directory (C:/Users/Mathias/Desktop) so the absolute path will be C:/Users/Mathias/Desktop/veryimportant.json
So what can you do?
You have the following options.
Option 1
Move the j.json file to the same directory as your p.py file
Option 2
Refer to j.json with the absolute path (looks something like this "C:/path/to/file.json" with your drive letter first)
I have a python script that compresses specific files into a zip file. However I have noticed that a file ".DS_Store" is produced within this zip file. Is there a way I can remove this from the zip file or avoid it being created in the first place in my python script. From what I have found online I think on a windows machine this hidden file appears as "macosx" file.
I've tested the zip file with and without the ".DS_Store" hidden file (I manually deleted it). When I remove it, the zip file is able to be processed correctly and when I leave it in, errors are thrown.
This is how I create the zip file in my python script:
#Create zip file of all necessary files
zipf = zipfile.ZipFile(new_path+zip_file_name, 'w', zipfile.ZIP_DEFLATED)
create_zip(new_path,zipf)
zipf.close()
Any advice how to approach removing this hidden file would be appreciated.
Your code uses a function, create_zip, but you haven't shared the code of that function. Presumably, it loops through the contents of a directory and calls the .write method of the ZipFile instance in order to write each file into the archive. If this is the case, just add some logic to that function to exclude any files called .DS_Store.
def create_zip(path, zipfile):
files = os.listdir(path)
for file in files:
if file != '.DS_Store':
zipfile.write(file)
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