So, I made this little "application" that checks if a file ends with a specific extension(.png or .jpg), but my issue is if I turn it into a loop and I download something while the loop is running it won't move the file to the intended location. It only moves the file on startup.
import os
import shutil
DownloadsDir = ""
Downloadslst = os.listdir(DownloadsDir)
ImageFolder = ''
while True:
for files in Downloadslst:
if files.endswith(('.png','.jpg')):
shutil.move(DownloadsDir + files, ImageFolder)
print("File moved succefully.")
os.listdir(...) is a one-time operation that lists all the files in the current directory at the point of calling. The collection is fixed, not dynamically updated; it's just a simple list. And lists don't update themselves based on a seemingly random condition, like when the files inside a directory change. If you want your list to stay updated, you need to call the function multiple times.
I would do:
processed = set()
to_process = set()
while has_smth_to_download:
download_some_files()
for item in os.listdir(DownloadsDir):
if item not in processed:
to_process.add(item)
processed.add(item)
for files in to_process:
if files.endswith(('png','.jpg')):
shutil.move(DownloadsDir + files, ImageFolder)
print("File moved succefully.")
to_process.clear()
try this:
import os
import shutil
DownloadsDir = ""
ImageFolder = ''
while True:
Downloadslst = os.listdir(DownloadsDir)
for files in Downloadslst:
if files.endswith(('.png','.jpg')):
shutil.move(DownloadsDir + files, ImageFolder)
print("File moved succefully.")
Related
I have to check in a while loop. I have found the following code it shows the file without while loop.
for file in glob.glob("*.txt"):
print(file)
but it does not work in a while loop if i use the following code
a = os.listdir(my_path)
#print(a)
for file in glob.glob("*.txt"):
print(file)
I am trying to program a watcher type in python with OS module
while True:
f = os.listdir(path)
if len(f) > 0:
for i in os.listdir(path):
if i.endswith('.txt'):
continue
else:
dosomething()
time.sleep(5) #so loop checks files every 5 sec
This way you only use os module, glob's not needed.
use os.listdir to get all files in a folder
len to get total files
list comprehension with sum and str.endswith to get count files ending with ".txt"
Demo:
import os
a = os.listdir(my_path)
if len(a) == sum(1 for i in a if i.endswith(".txt")):
print("All Text")
import os
dr = os.listdir(my_path)
if len(dr) == len(filename for filename, file_extension in a if file_extension == '.txt')):
#do stuff
pass
Well, from what i can understand, what you want is to create a watcher service to provide you if a new file is created.
`
import glob
files = glob.glob("*.txt") # Check first time all the files
while True: # till you exit
_old_files_count = len(files) # Get count of files
files = glob.glob("*.txt")
if len(files) > _old_files_count: # If new file is created.
print(*files[_old_files_count:], sep="\n") # Printing all new files in new line.
`
It will provide you with new files created in that particular directory.
Also, with some tweaks you can also get files which are deleted.
Hope it helps.
For using os, just use below instead of glob line.
import os
files = [file for file in os.listdir() if file.endswith("*.txt")]
I need to perform a loop in order to check during time if files having a given template are added into a directory.
In pseudo-code:
template = "START_*_hello_*.pdf"
while true:
while "file having template does not exist":
time.sleep(1)
found_file = get_existing_file
file_processing(found_file)
The os.path.exists(file_path) function needs the entire filename. How could I used a filename containing the * jolly character?
Thanks
Using the glob module you could write something like this:
import glob
template = "START_*_hello_*.pdf"
while True:
files = glob.glob(template)
if not files:
# no file matching template exists. Try again later.
time.sleep(1)
continue
# Process all existing files
for file in files:
file_processing(file)
I have an application. One method which will allow a directory path and returns list of file paths under given directory using os.walk
I would like to read certain no of files(some threshold value like bring 20 file paths) in a directory where has huge no files and stores in Queue. Here i can have a check of file path with its status in database.
Next time when i call the same method with same directory, it should return next set of file paths by excluding already returned file paths.
Scenario:
Lets assume, D:/Sample_folder has 1000 no of files.
my_dir = "D:/Sample_folder"
def read_files(directory):
file_paths = []
for root, directories, files in os.walk(directory):
for filename in files:
file_path = os.path.join(root, filename)
file_paths.append(file_path)
return file_paths
read_files(my_dir) == which will give first 100 no of files in first turn
Next turn, it should give remaining set of 100 files
like so...
Any ideas or sample scripts for this.
Assuming you already have files populated, this should do.
import Queue
paths = Queue.Queue()
current_list = []
for i, path in enumerate(files):
# Second case to make sure we dont add a blank list
if i % 100 == 0 and i != 0:
paths.put(current_list)
current_list = []
current_list.append(path)
EDIT:
Here is a possible solution using a class, but it doesn't add much code. The main idea is to pop off an element each time it gets accessed. So the workflow is to make a FileListIter object, then call .next() on it to return a list of the next 100 files to do something with and then the object forgets them. You can call .has_next() to check if you're out of files. If you pass an argument to next like .next(2), then it will instead give back the first 2 files in a list.
CODE:
import os
class FileListIter(object):
#Initialize the files
def __init__(self,directory):
file_paths = []
for root, directories, files in os.walk(directory):
for filename in files:
file_path = os.path.join(root, filename)
file_paths.append(file_path)
self.files = file_paths
#When called w/out args give back the first 100 files, otherwise the first n
def next(self,n=100):
ret,self.files = self.files[:n],self.files[n:]
return ret
#Check if there are any files left
def has_next(self):
return len(self.files) > 0
d = '/home/rob/stack_overflow'
files_gen = FileListIter(d) #<-- this makes an object
while files_gen.has_next():
file_subset = files_gen.next(2)
print file_subset
I'm trying to list all the html files in a single directory which works fine. However I'm trying to remove everything that is not a html file from that list as well.
i have 8 files called 1, 2, 3... etc. and 6.htmxl (remove) and pipe.sh.save(remove)
The code I made removes the .htmxl file but does not remove the .sh.save file from the list.
from os import listdir
from os.path import isfile, join
import pyimport
import time
def main():
onlyfiles = [f for f in listdir('/home/pi/keyboard/html') if isfile(join('/home/pi/keyboard/html',f)) ]
j = 0
print len(onlyfiles)
for i in onlyfiles:
if i.find(".html") == -1:
print i
print "not a html"
j = onlyfiles.index(i)
print j
del onlyfiles[j]
else:
print i
print "html found"
time.sleep(0.5)
outfiles = onlyfiles
print outfiles
return outfiles
if __name__ == "__main__":
main()
I also have another code which is suppose to get the "outfiles" list
import server_handler
files = server_handler.main()
fileList = server_handler.outfiles
But when I run it I get:
AttributeError: 'module' object has no attribute 'outfiles'
I'm running nearly the exact same code on another code which is creating 'output' and I import it in the exact same way so I'm not sure why its not importing correctly.
You might find the following approach more suitable, it uses Python's glob module:
import glob
print glob.glob('/home/pi/keyboard/html/*.html')
This will return you a list of all files in that folder ending in .html automatically.
Replace i.find(".html") with i.endswith(".html"). Now you should get only HTML files (or more precisely only files that look like HTML).
For the second part - remove:
fileList = server_handler.outfiles
server_handler.main() already returns the list so you have it in files. The last line doesn't make any sense.
EDIT:
Martin's answer has better way to get files. So I recommend you use his advice and not mine :).
This would work if main was a class, and you used
class main():
def __init__(self):
....
self.outfiles = onlyfiles
return self.outfiles
Im trying to create a single file out of multiple text files I have across multiple folders. This is my code for concatenating. It works only if the program file is placed in each folder:
import os
file_list = [each for each in cur_folder if each.endswith(".txt")]
print file_list
align_file = open("all_the_files.txt","w")
seq_list = []
for each_file in file_list:
f_o = open(file_path,"r")
seq = (f_o.read().replace("\n",""))
lnth = len(seq)
wholeseq = ">"+each_file+" | "+str(lnth)+" nt\n"+seq+"\n"
align_file.write(wholeseq)
print "done"
Now I tried to edit to make sure that it automatically runs through the entire Data folder and then enters the subdirectories and concatenates all the files without me having to paste the program file in each folder. This is the edit.
import os
dir_folder = os.listdir("C:\Users\GAMER\Desktop\Data")
for each in dir_folder:
cur_folder = os.listdir("C:\\Users\\GAMER\\Desktop\\Data\\"+each)
file_list = []
file_list = [each for each in cur_folder if each.endswith(".txt")]
print file_list
align_file = open("all_the_files.txt","w")
seq_list = []
for each_file in file_list:
f_o = open(file_path,"r")
seq = (f_o.read().replace("\n",""))
lnth = len(seq)
wholeseq = ">"+each_file+" | "+str(lnth)+" nt\n"+seq+"\n"
align_file.write(wholeseq)
print "done" , cur_folder
However when I run this , I get an error on the first file of the folder saying no such file exists. I can seem to understand why, specifically since it names the file which is not "hardcoded". Any help will be appreciated.
If the code looks ugly to you feel free to suggested better ways to do it.
Jamie is correct - os.walk is most likely the function you need.
An example based on your use case:
for root, dirs, files in os.walk(r"C:\Users\GAMER\Desktop\Data"):
for f in files:
if f.endswith('.txt'):
print(f)
This will print the name of every single file within every folder within the root directory passed in os.walk, as long as the filename ends in .txt.
Python's documentation is here: https://docs.python.org/2/library/os.html#os.walk