Odczyt zawartości plików w folderze

0

Istnieje folder z plikami.
Pliki mają dziwne nazwy (ciągi alfanumeryczne). Nie są żadnego typu.
title
Każdy plik zawiera jedną linię: location: dir(numer od 1 do 3)

Próbuję odczytać każdy plik, ale coś robię nieumiejętnie.

# -*- coding: utf-8 -*-

sciezka= 'C:/!own/Python_scripts/resources/lab2/files'
#sciezka= 'C:\!own'

import os
lista_plikow=os.listdir(sciezka)

print(lista_plikow)

for i in lista_plikow:
   otworz=open(i)
   zawartosc=i.read
   print(zawartosc)

FileNotFoundError: [Errno 2] No such file or directory: 'tmp0gjxV1'

Jeśli zrobię w pętli print(i) to nazwa pliku wydaje się wyświetlać poprawnie, a jednak odczytać nie mogę.

Generalnie po odczycie pliku, trzeba utworzyć folder o nazwie dir(numer od 1 do 3) i skopiować do niego dany plik.

1

Skąd odpalasz skrypt Python? Zauważ, że do folderu 'files' podajesz pełną ścieżkę i Python 'wie' gdzie szukać. A lista_plikow to po prostu lista nazw plików - nie wiadomo jaka jest ich lokalizacja (jeżeli nie jest to ścieżka pełna - absolutna - Python sprawdza bieżący folder, z którego odpalany jest skrypt no i tyle).

Więc musisz podać pełną ścieżkę i najlepiej użyć os.path.join (moglibysmy np. po prostu dodać dwa stringi ale czasami są dziwne sytuacje typu różne znaki folderów / \ itp i ta funkcja rozwiązuje to):

os.path.join(sciezka, i)

Ale idąc dalej zasugeruję pewną zmianę. Wykorzystanie komendy open() wymusza stosowanie close(). Zdarza się to zapomnieć ale też close() nie wykona się jeżeli np. dojdzie do wyjątku w połowie kodu. Dlatego stosuje się tzw. context handler, który 'zarządza życiem zasobu' i zwolni zasób gdy zakończymy z nim pracę. Przykład:

with open(i) as f:
    content = f.read()
    print(content)
0

Miałeś rację!
Skrypt mam na Desktop

Zmieniłem na taki

# -*- coding: utf-8 -*-

sciezka= 'C:/!own/Python_scripts/resources/lab2/files'
#sciezka= 'C:\!own'

import os
lista_plikow=os.listdir(sciezka)

print(lista_plikow)

for i in lista_plikow:
    pelna_sciezka=os.path.join(sciezka,i)
    print(pelna_sciezka)
    otworz=open(pelna_sciezka)
    #print(otworz)
    zawartosc=pelna_sciezka.read()
    #print(zawartosc)

Tylko teraz jest taki błąd: AttributeError: 'str' object has no attribute 'read'

Python nie wie, że to plik?

0

Tylko teraz jest taki błąd: AttributeError: 'str' object has no attribute 'read'

Python nie wie, że to plik?

Zrób tak jak sugerował @AsterFV. I będzie gitarzyć :D

0

Dzięki.
Działa jak złoto. W pierwszej chwili nie załapałem jak to połączyć.

Idę teraz krok dalej:
wycięcie dir(numer od 1 do 5) z zawartości, i utworzenie takiego folderu w podanej ścieżce

# -*- coding: utf-8 -*-

sciezka= 'C:/!own/Python_scripts/resources/lab2/files'

import os
lista_plikow=os.listdir(sciezka)

print(lista_plikow)

for i in lista_plikow:
    pelna_sciezka=os.path.join(sciezka,i)
    with open(pelna_sciezka) as f:
        zawartosc=f.read()
        print(zawartosc)
        podzial=zawartosc.split()
        print(podzial)
        folder=podzial[1]
        print(folder)
        nowy_folder=os.path.join(sciezka,folder)
        print(nowy_folder)
        try:
            os.mkdir(nowy_folder)
            print("Folder ",nowy_folder," utworzony.")
        except FileExistsError:
           print("Folder ",nowy_folder," już istnieje.")

Pytanie czy można to jakoś skrócić?
Oczywiście print'y usunę na koniec :)

I ostatni krok: kopiowanie pliku do odpowiedniego folderu. OS mi chyba tego nie zrobi?

0

Przeprowadzasz śmiałe założenie, że pliki faktycznie mają 'location: dir(numer od 1 do 3)' w pierwszej linijce ;) Ale jeżeli pliki są z zaufanego źródła i skrypt jest dla Ciebie to można tak przyjąć (w sensie, że nie sprawdamy np. czy plik jest pusty albo ma inna zawartość, albo nie jest plikiem txt).

Interesuje nas tylko pierwsza linia więc zamiast wczytywać cały plik możemy wczytać jedną linijkę:

first_line = f.readline()

Metody w Pythonie możemy 'chainowac' (wykonywać ciagiem) więc dla skrócenia - o ile faktycznie jesteśmy pewni formatu tej linijki - możemy napisać:

dir_name = f.readline().split()[1]

Możesz spróbowac oddzielić otwieranie plików i uzyskiwanie nazwy folderu a późniejsze tworzenie:

dir_names = []
for i in lista_plikow:
    pelna_sciezka=os.path.join(sciezka,i)
    with open(pelna_sciezka) as f:
        dir_name = f.readline().split()[1]
        dir_names.append(dir_name)

for dir_name in dir_names:
        try:
            os.mkdir(dir_name)
            print("Folder ",nowy_folder," utworzony.")
        except FileExistsError:
           print("Folder ",dir_name," już istnieje.")
1

https://stackoverflow.com/questions/123198/how-do-i-copy-a-file-in-python

Tu masz przykład kopiowania, pod spodem jeszcze masz tabelkę zawierającą różne opcje - zależnie od efektu który chcesz uzyskać.

Co do 'skrócenia'. Kod jest czytelny, nie ma potrzeby :).
Kod krótszy nie jest szybszy, chyba że zależy ci na jego rozmiarze...

# -*- coding: utf-8 -*-
 
sciezka= 'C:/!own/Python_scripts/resources/lab2/files'
 
import os
lista_plikow=os.listdir(sciezka)
 
print(lista_plikow)
 
for i in lista_plikow:
    pelna_sciezka=os.path.join(sciezka,i)
    with open(pelna_sciezka) as f:
        zawartosc=f.read().split()[1]
        nowy_folder=os.path.join(sciezka,zawartosc)
        try:
            os.mkdir(nowy_folder)
            print("Folder ",nowy_folder," utworzony.")
        except FileExistsError:
           print("Folder ",nowy_folder," już istnieje.")

Nie testowałem, ale powinno działać. :)

0

To nie moje założenie, a podstawa zadania :).

W folderze resources/lab2/files zlokalizowanym w repozytorium znajduje się szereg plików o losowych nazwach. W każdym z plików znajduje się tylko jeden wiersz o postaci: location: [nazwa folderu], gdzie [nazwa folderu] może różnić się pomiędzy plikami. Należy skopiować poszczególne pliki zawarte w podanej lokalizacji do folderów, których nazwy są takie same jak ta podana wewnątrz pliku.

Nie szukam gotowych rozwiązań, bo się średnio nauczę, a naprowadzenia :)
Wielkie dzięki za wszelkie podpowiedzi.

0

Może ktoś jeszcze zerknąć na kod?
Dodanie shutil.copy działa tylko za pierwszym razem, lub gdy utworzone foldery dir(numer od 1 do 5) nie istnieją.
Próba kolejnego wykonania zwraca błąd:
PermissionError: [Errno 13] Permission denied: 'C:/!own/Python_scripts/resources/lab2/files\dir1'
Wg dokumentacji shutil powinien nadpisywać pliki. Ale może problem jest związany z tworzeniem folderów?

# -*- coding: utf-8 -*-
 
sciezka= 'C:/!own/Python_scripts/resources/lab2/files'
 
import os
import shutil
lista_plikow=os.listdir(sciezka)
 
print(lista_plikow)
 
for i in lista_plikow:
    pelna_sciezka=os.path.join(sciezka,i)
    with open(pelna_sciezka) as f:
        zawartosc=f.read().split()[1]
        nowy_folder=os.path.join(sciezka,zawartosc)
        try:
            os.mkdir(nowy_folder)
            print("Folder ",nowy_folder," utworzony.")
        except FileExistsError:
           print("Folder ",nowy_folder," już istnieje.")
        shutil.copy(pelna_sciezka,nowy_folder)
0
# -*- coding: utf-8 -*-

sciezka= r'C:/!own/Python_scripts/resources/lab2/files'

import os
import shutil
lista_plikow=os.listdir(sciezka)

print(lista_plikow)

for i in lista_plikow:
    pelna_sciezka=os.path.join(sciezka,i)
    print(pelna_sciezka)
    with open(pelna_sciezka) as f:
        zawartosc=f.read()
        print(zawartosc)
        podzial=zawartosc.split()
        print(podzial)
        folder=podzial[1]
        print(folder)
        nowy_folder=os.path.join(sciezka,folder)
        print(nowy_folder)
        try:
            os.mkdir(nowy_folder)
            print("Folder ",nowy_folder," utworzony.")
        except FileExistsError:
           print("Folder ",nowy_folder," już istnieje.")
        #print(os.path.isfile(pelna_sciezka))
        #print(pelna_sciezka)
        #print(nowy_folder)
        #shutil.copy(pelna_sciezka,nowy_folder)

Jeśli raz zostanie wykonane i foldery istnieja to jest taki błąd.
**Traceback (most recent call last): File "C:\Users\u1150393\Desktop\pliki.py", line 14, in <module> with open(pelna_sciezka) as f: PermissionError: [Errno 13] Permission denied: 'C:/!own/Python_scripts/resources/lab2/files\\dir1'**

0

Ok miałem chwilkę czasu i i spojrzałem. Z tego co widzę pliki, które czytasz i tworzone foldery znajdują się w tym samym katologu. Więc za pierwszym razem jest ok i otwiera pliki i tworzy katologi. Przy drugiej iteracji skryptu jednak zauważ, że lista_plikow=os.listdir(sciezka) pobiera wszystko co w folderze (a więc pliki i foldery). Następnie wykonujesz with open(pelna_sciezka) as f: czyli próbujesz otworzyć folder jak plik.

Jak temu zaradzić? Np. zamiast os.listdir użyć os.walk albo po prostu ominąć foldery wykonując pętlę:

for i in lista_plikow:
    pelna_sciezka=os.path.join(sciezka,i)
    if os.path.isdir(pelna_sciezka):
        continue
0

Tak, pełna racja.
Nie wiem jak nie zauważyłem, że foldery chciał czytać najpierw. Nawet w linku była nazwa folderu.
To się chyba nazywa przemęczenie materiału.

Dodatkowo dopisałem try dla shutil.
Teraz to wygląda tak:

sciezka= r'C:\!own\Python_scripts\resources\lab2\files'
 
import os
import shutil
lista_plikow=os.listdir(sciezka)
 
print(lista_plikow)
 
for i in lista_plikow:
    pelna_sciezka=os.path.join(sciezka,i)
    if os.path.isdir(pelna_sciezka):
        continue
    with open(pelna_sciezka) as f:
        zawartosc=f.read().split()[1]
        nowy_folder=os.path.join(sciezka,zawartosc)
        try:
            os.mkdir(nowy_folder)
            print("Folder '",zawartosc,"' w ",sciezka," został utworzony.")
        except FileExistsError:
           print("Folder '",zawartosc,"' już istnieje.")
        try:
            shutil.copy(pelna_sciezka,nowy_folder)
            print("Plik '",i,"' został skopiowany/nadpisany do/w ",nowy_folder,".\n")
        except (shutil.Error, IOError):
            print("Skopiowanie/Nadpisanie pliku '",i,"' niemożliwe.\n")

Jeszcze raz dziękuję za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1