Zamykanie plików i obsługa błędów
Proszę prawidłowo zamykać uchwyty plików i obsługiwać błędy io za pomocą pcall.
Zamykanie plików i obsługa błędów to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Lua Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Lua Academy zawiera 4 lekcji w sumie.
Zawsze zamykaj pliki
Każdy plik otwarty za pomocą io.open należy zamknąć przy użyciu f:close(). Niezamknięte pliki powodują wycieki deskryptorów plików. Garbage collector Lua ostatecznie je zamknie, ale zanim to nastąpi, można wyczerpać limity plików systemu operacyjnego. Zawsze zamykaj plik w funkcji, która go otworzyła.
local function readFile(path)
local f, err = io.open(path, "r")
if not f then return nil, err end
local content = f:read("a")
f:close() -- always close
return content
end
local data, err = readFile("config.txt")
if not data then print("Error:", err) endpcall dla bezpiecznej obsługi operacji wejścia-wyjścia
Owiń operacje na plikach w pcall, aby przechwytywać nieoczekiwane błędy (pełny dysk, odmowa dostępu w trakcie zapisu). Dzięki temu można poprawnie obsłużyć błędy zamiast doprowadzać do awarii programu.
local function safeCopy(src, dst)
local ok, err = pcall(function()
local f = io.open(src, "rb")
if not f then error("Cannot open source: " .. src) end
local content = f:read("a")
f:close()
local g = io.open(dst, "wb")
if not g then error("Cannot open dest: " .. dst) end
g:write(content)
g:close()
end)
return ok, err
end
local ok, msg = safeCopy("input.txt", "output.txt")
if not ok then print("Failed:", msg) endSprawdzanie powodzenia zapisu
Na systemach z pełnym dyskiem lub problemami z uprawnieniami funkcja f:write() może się nie powieść, nawet jeśli io.open zakończyło się pomyślnie. W krytycznych fragmentach kodu należy sprawdzać wartości zwracane przez operacje zapisu.
local f = io.open("important.txt", "w")
if not f then
print("Cannot create file")
return
end
local ok, err = f:write("critical data\n")
if not ok then
print("Write failed:", err)
f:close()
return
end
f:close()
print("Saved successfully")Wzorzec finally z pcall
Lua nie ma bloku finally, ale można go zasymulować za pomocą pcall. Umieść ryzykowny kod w pcall, a po jego zakończeniu (niezależnie od powodzenia lub błędu) bezwarunkowo wykonaj kod sprzątający, zanim ponownie zgłosisz błąd lub go obsłużysz.
local function withFile(path, mode, fn)
local f, err = io.open(path, mode)
if not f then return nil, err end
local ok, result = pcall(fn, f)
f:close() -- always close, even on error
if not ok then
return nil, result
end
return result
end
local content, err = withFile("data.txt", "r", function(f)
return f:read("a")
end)
print(content or err)Komunikaty błędów z io.open
io.open zwraca nil oraz systemowy komunikat błędu i kod błędu. Komunikat zawiera ścieżkę oraz przyczynę błędu systemu operacyjnego ("No such file", "Permission denied" itd.). W raporcie błędu dla użytkownika należy zawsze uwzględnić komunikat błędu.
local paths = {"config.txt", "missing.txt", "/root/secret.txt"}
for _, path in ipairs(paths) do
local f, err, code = io.open(path, "r")
if f then
print(path, "-> ok, size:", f:seek("end"))
f:close()
else
print(path, "-> ERROR:", err, "(code "..tostring(code)..")")
end
endUchwyt pliku jako obiekt
Uchwyt pliku w Lua jest wartością userdata wyposażoną w metody. Po zebraniu uchwytu przez garbage collector plik jest automatycznie zamykany. Nie należy jednak polegać na garbage collectorze, jeśli plik ma zostać zamknięty w określonym czasie — zawsze zamykaj go jawnie. Można sprawdzić, czy plik jest zamknięty, wywołując f:read() — dla zamkniętego uchwytu wystąpi błąd.
local f = io.open("test.txt", "w")
f:write("test\n")
-- Explicit close
f:close()
-- After close, operations fail
local ok, err = pcall(function()
f:read() -- attempt to use closed file
end)
print(ok, err) -- false [closed file]Bezpieczny szablon przetwarzania plików
Wielokrotnego użytku szablon bezpiecznego przetwarzania plików: otwórz plik i sprawdź błąd, przetwórz dane za pomocą pcall, a następnie zamknij plik w każdym przypadku. Zwracaj wyniki i błędy w spójny sposób, stosując konwencję nil+message.
local function processFile(path, processor)
local f, err = io.open(path, "r")
if not f then return nil, "open failed: " .. err end
local ok, result = pcall(processor, f)
f:close()
if not ok then
return nil, "processing failed: " .. result
end
return result
end
local lineCount, err = processFile("data.txt", function(f)
local n = 0
for _ in f:lines() do n = n + 1 end
return n
end)
print(lineCount or err)os.remove i os.rename
os.remove(path) usuwa plik. os.rename(old, new) zmienia nazwę pliku lub przenosi go. Obie funkcje zwracają true po pomyślnym wykonaniu albo nil, errMessage w przypadku błędu. Są to podstawowe funkcje standardowej Lua do operowania na systemie plików.
-- Delete a file
local ok, err = os.remove("temp.txt")
if not ok then print("Remove failed:", err) end
-- Rename / move
ok, err = os.rename("old_name.txt", "new_name.txt")
if not ok then print("Rename failed:", err) end
-- Atomic update pattern
os.rename("config.new", "config.txt")io.close a f:close
io.close(f) jest równoważne f:close(). Wywołanie io.close() bez argumentu zamyka domyślny plik wyjściowy. W większości kodu należy używać f:close() dla większej czytelności.
local f = io.open("test.txt", "w")
f:write("hello\n")
-- Both are equivalent:
-- f:close()
io.close(f)
-- io.close() with no arg closes default output
io.output("out.txt")
io.write("to file\n")
io.close() -- closes out.txt, restores stdoutSolidne kopiowanie plików
Kopiowanie pliku na poziomie produkcyjnym z obsługą błędów na każdym etapie: otwarcie źródła, otwarcie miejsca docelowego, kopiowanie partiami, obsługa błędów zapisu oraz zamknięcie obu plików.
local function copyFile(src, dst, chunkSize)
chunkSize = chunkSize or 65536
local fsrc, err1 = io.open(src, "rb")
if not fsrc then return nil, err1 end
local fdst, err2 = io.open(dst, "wb")
if not fdst then fsrc:close(); return nil, err2 end
local ok = true
local chunk = fsrc:read(chunkSize)
while chunk and ok do
local w, werr = fdst:write(chunk)
if not w then ok = false; err2 = werr end
chunk = fsrc:read(chunkSize)
end
fsrc:close(); fdst:close()
if not ok then os.remove(dst); return nil, err2 end
return true
endSzybkie sprawdzenie
Jaki jest najlepszy sposób, aby zagwarantować zamknięcie pliku w Lua nawet w przypadku wystąpienia błędu?
Podsumowanie: zamykanie i obsługa błędów
Podsumowanie:
- Zawsze jawnie wywołuj
f:close()— nie polegaj na garbage collectorze - Owijaj operacje wejścia-wyjścia w pcall, aby zapewnić solidną obsługę błędów
- Używaj schematu "otwórz → pcall → zamknij"
os.remove/os.renamesłużą do operacji na systemie plików- W krytycznym kodzie sprawdzaj wartości zwracane przez operacje zapisu
Ucz się Lua dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 40
- Lekcje
- 159
Często zadawane pytania
Czy lekcja „Zamykanie plików i obsługa błędów” jest bezpłatna?
Tak — pełny tekst „Zamykanie plików i obsługa błędów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Lua Academy, przejdź na CoddyKit PRO. Kurs Lua Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Zamykanie plików i obsługa błędów”?
Proszę prawidłowo zamykać uchwyty plików i obsługiwać błędy io za pomocą pcall. Ćwiczysz Lua Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Lua Academy?
Nie wymagamy żadnego doświadczenia. Lua Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Zamykanie plików i obsługa błędów”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Lua Academy?
Tak. Każda lekcja Lua Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Otwieranie plików za pomocą io.open
- Odczytywanie zawartości plików
- Zapisywanie i dopisywanie do plików
- Zamykanie plików i obsługa błędów