-3

Im trying to get a local directory from argv and iterate through the folder and print the contents of each file within. However i am getting a [Errno] 13 saying permission denied. Ive tried researching the problem but have come up empty handed.

#!/usr/bin/python
import os
import sys


path = open(sys.argv[1],'r')   #'inputs/' path to working input dir
file_list = os.listdir(path)    #create list of filenames in path dir
for fn in file_list:
    file = open(path+'/'+fn)        #open each file in dir for manipulation
    for line in file:
        print(line)
hashbyte
  • 121
  • 1
  • 4
  • 10

1 Answers1

1

os.listdir(), as its name implies, returns a list of all occupants of the given directory, including both files and directories (and, if you're on Unix/Linux, other stuff like symlinks and devices and whatnot). You are then blindly trying to open() each item in the list and print() its contents. Unfortunately, open() only works on file-like objects, and specifically does not work on directories, hence Errno 13, Permission Denied.

An alternative is to use os.scandir(), which works a little bit differently. Instead of returning a flat list that you can read immediately, os.scandir() returns a generator which essentially gives you objects as you ask for them, instead of giving them all to you at once. In fact, the following code adapted from the docs is a good starting place for what you need:

for entry in os.scandir(path):
    if entry.is_file():
       print(entry.name)

os.scandir() is returning DirEntry objects. Simply use os.path.join() to create a full pathname out of the path argument you pass to os.listdir() in your original code, and entry.name from the code above, and then, using the with context manager, open() the file and display its contents:

for entry in os.scandir(path):
    if entry.is_file():
       with open(os.path.join(path, entry), "r") as f:
           for line in f:
               print(line)

One of the advantages of using with is that you don't have to remember to close the file handle that is assigned when you use something like this:

f = open("myfile.txt, "r")
# do stuff with f
...
f.close()

Otherwise, you have a dangling file handle that could potentially cause problems, depending on how many there are and what you've done with them. It's just a good practice to close() what you open(). With with, you don't have to worry about it - the file handle is closed as soon as you exit the block.

Community
  • 1
  • 1
MattDMo
  • 100,794
  • 21
  • 241
  • 231