Odczyt zawartości plików w folderze

Odpowiedz Nowy wątek
2019-01-07 13:56
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.

edytowany 3x, ostatnio: aPsikus, 2019-01-07 13:58

Pozostało 580 znaków

2019-01-07 14:10
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)
edytowany 1x, ostatnio: AsterFV, 2019-01-07 14:12

Pozostało 580 znaków

2019-01-07 14:44
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?

edytowany 1x, ostatnio: aPsikus, 2019-01-07 14:45
Bo próbujesz otworzyć pelna_sciezka (czyli zmienną typu str) zamiast otworz - czyli zmienną typu file, którą zadeklarowałeś wyżej :) - AsterFV 2019-01-07 14:56

Pozostało 580 znaków

2019-01-07 14:54
lhp
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


Pozostało 580 znaków

2019-01-07 15:41
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?

edytowany 1x, ostatnio: aPsikus, 2019-01-07 15:44

Pozostało 580 znaków

2019-01-07 15:51
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.")
edytowany 1x, ostatnio: AsterFV, 2019-01-07 15:52

Pozostało 580 znaków

2019-01-07 15:52
1

https://stackoverflow.com/que[...]ow-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ć. :)


Linux Mint
Arduino / Python 3.5.2
edytowany 1x, ostatnio: Guaz, 2019-01-07 15:52
Oto właśnie mi chodziło :) Czy można jakoś zagnieżdżać kroki. Dzięki. Działa - aPsikus 2019-01-07 16:00
Odnośnie shutil: ogarnąłem go, ale cały proces działa tylko raz. Po skopiowaniu kolejne uruchomienie zwraca PermissionError: [Errno 13] Permission denied. Czy to znaczy, że tego shutil też trzeba w try: except: umieścić? A może co innego jest przyczyną błędu? - aPsikus 2019-01-07 16:18
Jeśli wyrzuca błąd gdy już masz tam jakiś plik. To jeśli chcesz aby go nadpisał, to powinieneś obsłużyć poprzez try/except, usunąć plik i wtedy go skopiować :). - Guaz 2019-01-07 16:38
Z dokumentacji o shutil automatycznie nadpisuje. Także to nie to. - aPsikus 2019-01-07 16:55

Pozostało 580 znaków

2019-01-07 15:55
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.

edytowany 2x, ostatnio: aPsikus, 2019-01-07 15:57
Nawet jak się nauczysz, niektóre rzeczy i tak zapomina się po kilku projektach/miesiącach. Więc sprowadza się to do googlowania :D - Guaz 2019-01-07 16:04
No dobra, może przesadziłem z tą nauką :P Miałem na myśli zrozumienie :) - aPsikus 2019-01-07 16:14

Pozostało 580 znaków

2019-01-07 16:33
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)
edytowany 1x, ostatnio: aPsikus, 2019-01-07 16:34
Pokaż pozostałe 7 komentarzy
Głupia rzecz ale spróbuj odpalić skrypt z uprawnieniami admina - AsterFV 2019-01-07 21:04
Mam na tym koncie uprawnienia administratorskie. Poza tym w podmenu dla prawego klawisza nie ma run as admin. Czy ma jakieś znaczenie, że w ścieżce w błędzie są podwójne slashe? - aPsikus 2019-01-07 21:06
Jeżeli poprzedziłeś string z r' to już nie używaj podwójnych slashy - AsterFV 2019-01-07 21:28
Teraz to już nie rozumiem... - aPsikus 2019-01-07 22:03
Bo to były alternatywne sposoby. np. r'C:\jakas\sciezka' to jest to samo co 'C:\jakas\sciezka' - AsterFV 2019-01-07 22:05

Pozostało 580 znaków

2019-01-07 22:04
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'**

edytowany 2x, ostatnio: aPsikus, 2019-01-07 22:06
Miałeś dać r'' i slashe w lewo. Nawet zauważ jak adres skryptu został wypisany "C:\Users\u1150393\Desktop\pliki.py". Slashe w lewo ;) Potem jak wystąpią błędy to z innego powodu. - AsterFV 2019-01-07 22:09
sciezka= r"C:!own\Python_scripts\resources\lab2\files" **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'** Teraz dopiero zrobiło się ciekawie. Są podwójne. A błąd jakby nadal dotyczył tego samego. - aPsikus 2019-01-07 22:12
Nie jestem windowsowcem... Ale powinno po C: być \\!own\\(...) ? Może to jakiś problem przy windowsie z bibliotekami? - Guaz 2019-01-08 01:22

Pozostało 580 znaków

2019-01-08 21:15
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

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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