0Pricing
Lua Academy · Урок

Чтение содержимого файлов

Читайте строки, байты и всё содержимое с помощью методов file:read().

«Чтение содержимого файлов» — бесплатный урок Lua Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.

Чтение всего файла

Используйте f:read("a") (или "*a"), чтобы считать весь файл в строку. Это простой и подходящий способ для файлов малого и среднего размера. Для очень больших файлов считывайте данные блоками или построчно, чтобы избежать проблем с памятью.

local f = io.open("config.txt", "r")
if f then
  local content = f:read("a")
  f:close()
  print("Size:", #content, "bytes")
  print(content)
end

Построчное чтение

f:read("l") считывает следующую строку, удаляя перевод строки. При достижении EOF возвращается nil. Используйте цикл while, чтобы обработать каждую строку. f:lines() — идиоматичная краткая запись, выполняющая ту же задачу.

local f = io.open("data.txt", "r")
if f then
  local line = f:read("l")
  while line ~= nil do
    print(line)
    line = f:read("l")
  end
  f:close()
end

-- Equivalent with for loop:
-- for line in io.lines("data.txt") do print(line) end

Чтение заданного числа байтов

Передайте число в f:read(n), чтобы считать ровно n байтов. Возвращается строка длиной не более n байтов; если достигнут EOF, она может быть короче. При EOF возвращается nil. Этот способ используется для двоичных протоколов и структурированных форматов файлов.

local f = io.open("binary.dat", "rb")
if f then
  -- Read 4-byte header
  local header = f:read(4)
  if header then
    print("Header bytes:", #header)
    for i = 1, #header do
      io.write(string.format("%02X ", header:byte(i)))
    end
    print()
  end
  f:close()
end

Чтение числа

f:read("n") считывает из файла следующее число, пропуская пробельные символы. Возвращается число Lua или nil, если следующий токен не является числом. Это удобно для чтения структурированных файлов с числовыми данными.

-- File contains: "10 20 30.5 40"
local f = io.open("nums.txt", "r")
if f then
  local total = 0
  local n = f:read("n")
  while n do
    total = total + n
    n = f:read("n")
  end
  f:close()
  print("Sum:", total)
end

Перемещение по файлу

f:seek(whence, offset) перемещает текущую позицию в файле. Параметр whence принимает значение "set" — от начала, "cur" — от текущей позиции или "end" — от конца. Возвращается новая абсолютная позиция. Используйте эту функцию, чтобы повторно прочитать данные или перейти к другой части файла.

local f = io.open("test.txt", "r")
if f then
  -- Jump to end, get file size
  local size = f:seek("end")
  print("File size:", size, "bytes")
  
  -- Seek back to start
  f:seek("set", 0)
  local first_line = f:read("l")
  print("First line:", first_line)
  f:close()
end

Чтение CSV-файлов

Разбирайте данные CSV построчно: считывайте каждую строку, а затем разделяйте её по запятым с помощью string.gmatch. В рабочих приложениях учитывайте поля в кавычках и запятые внутри них, а для простых данных достаточно базового разделения.

local function parseCSV(path)
  local rows = {}
  for line in io.lines(path) do
    local row = {}
    for field in string.gmatch(line, "([^,]+)") do
      row[#row+1] = field
    end
    rows[#rows+1] = row
  end
  return rows
end

-- Example: "Alice,30,Engineer"
-- => {{"Alice","30","Engineer"}}

Чтение файлов конфигурации

Простой формат конфигурации key=value: считывайте данные построчно, пропускайте комментарии и пустые строки, а пары key=value разбирайте с помощью string.match.

local function loadConfig(path)
  local cfg = {}
  for line in io.lines(path) do
    -- Skip comments and blank lines
    if not line:match("^%s*#") and line:match("%S") then
      local k, v = line:match("^%s*(%w+)%s*=%s*(.-)%s*$")
      if k then cfg[k] = v end
    end
  end
  return cfg
end

local config = loadConfig("app.conf")
print(config.host, config.port)

Чтение блоками

При работе с большими файлами считывайте данные блоками фиксированного размера, чтобы не загружать всё содержимое в память. Обрабатывайте каждый блок по мере его поступления. Это особенно важно для файлов, размер которых превышает доступный объём RAM.

local function processLarge(path, chunkSize)
  chunkSize = chunkSize or 4096
  local f, err = io.open(path, "rb")
  if not f then return nil, err end
  local totalBytes = 0
  local chunk = f:read(chunkSize)
  while chunk do
    totalBytes = totalBytes + #chunk
    -- process chunk here
    chunk = f:read(chunkSize)
  end
  f:close()
  return totalBytes
end

Чтение нескольких значений в строке

Если каждая строка содержит несколько значений, разделённых пробелами или табуляцией, используйте string.match или string.gmatch, чтобы извлечь их. Этот шаблон подходит для простых структурированных текстовых файлов.

-- File: "Alice 95 A\nBob 87 B"
local results = {}
for line in io.lines("grades.txt") do
  local name, score, grade = line:match("(%S+)%s+(%d+)%s+(%S+)")
  if name then
    results[#results+1] = {
      name=name,
      score=tonumber(score),
      grade=grade
    }
  end
end

for _, r in ipairs(results) do
  print(r.name, r.score, r.grade)
end

Сокращённая запись io.lines

io.lines(filename) открывает файл, возвращает итератор строк и закрывает файл после завершения работы. Это самый краткий способ читать файл построчно без явного управления дескриптором.

-- Count non-empty lines
local count = 0
for line in io.lines("data.txt") do
  if line:match("%S") then
    count = count + 1
  end
end
print("Non-empty lines:", count)

-- Collect all lines into a table
local lines = {}
for line in io.lines("data.txt") do
  lines[#lines+1] = line
end
print("Total lines:", #lines)

Быстрая проверка

Что возвращает f:read("a"), если указатель файла уже находится в EOF?

Повторение: чтение файлов

Краткое резюме:

  • f:read("a") — весь файл в виде строки
  • f:read("l") — одна строка без перевода строки
  • f:read(n) — ровно n байтов
  • f:read("n") — следующее число
  • io.lines(path) — итератор строк с автоматическим закрытием
  • f:seek() — переход к определённой позиции

Часто задаваемые вопросы

Урок «Чтение содержимого файлов» бесплатный?

Да — полный текст урока «Чтение содержимого файлов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.

Чему я научусь в уроке «Чтение содержимого файлов»?

Читайте строки, байты и всё содержимое с помощью методов file:read(). Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Lua Academy?

Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Чтение содержимого файлов»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Lua Academy?

Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Открытие файлов с io.open
  2. Чтение содержимого файлов
  3. Запись и добавление в файлы
  4. Закрытие файлов и обработка ошибок
← Назад к Lua Academy