Proyek analisis nyata tidak pernah hidup dalam satu folder: data mentah datang dari data/, hasil tersimpan ke output/, dan berkas sementara harus dibersihkan setiap kali script dijalankan ulang. Melakukan semua itu manual lewat file explorer membuat pekerjaan tidak terulang dengan andal — MATLAB memberi perangkat lengkap untuk mengelola berkas dari dalam kode. Cakupan chapter ini:

  • Meninjau isi folder dengan dir dan wildcard *.csv
  • Menyusun path portabel dengan fullfile dan filesep
  • Memeriksa keberadaan berkas/folder dengan exist, isfile, dan isfolder
  • Membuat, menyalin, memindah, menghapus: mkdir, copyfile, movefile, delete, rmdir
  • Menelusuri folder secara rekursif dan menata struktur proyek

dir: Inventaris Berkas dengan Wildcard #

Aturannya: dir(pola) mengembalikan struct array — satu elemen per berkas/folder yang cocok dengan pola. Mekanismenya: wildcard * menggantikan deretan karakter apa pun, sehingga dir(fullfile('data', '*.csv')) hanya menangkap berkas berakhiran .csv. Tiap elemen struct memuat field:

FieldIsiKeterangan
.namenama berkas tanpa folderkunci untuk loop pemrosesan
.folderfolder tempat berkas beradaberguna saat dir multi-folder
.bytesukuran berkas dalam byteaudit ukuran data
.isdirtrue bila berupa foldermemilah folder dari berkas
.datewaktu modifikasi terakhirmenemukan berkas termutakhir
matlab
mkdir('data');
fid = fopen(fullfile('data', 'a.csv'), 'w'); fprintf(fid, '1,2\n'); fclose(fid);
fid = fopen(fullfile('data', 'b.csv'), 'w'); fprintf(fid, '3,4\n'); fclose(fid);
fid = fopen(fullfile('data', 'catatan.txt'), 'w'); fprintf(fid, 'catatan\n'); fclose(fid);

L = dir(fullfile('data', '*.csv'));
fprintf('jumlah *.csv: %d\n', numel(L));
for k = 1:numel(L)
  fprintf('file %d: %s (%d byte)\n', k, L(k).name, L(k).bytes);
end

Output yang Dihasilkan:

text
jumlah *.csv: 2
file 1: a.csv (4 byte)
file 2: b.csv (4 byte)

Mari kita bedah baris-baris kode di atas:

  1. Baris 6 (dir(fullfile('data', '*.csv'))): pola diterapkan pada folder data, bukan folder kerja — catatan.txt tidak ikut karena ekstensinya tidak cocok.
  2. Baris 7 (numel(L)): hasil dir adalah struct array yang bisa kosong; numel = 0 berarti tidak ada berkas cocok — kondisi yang layak diperiksa sebelum loop.
  3. Baris 8-10 (L(k).name, L(k).bytes): loop membaca field per elemen; bila urutan hasil penting, tambahkan sort({L.name}) karena urutan dir bergantung sistem operasi.

fullfile dan filesep: Path yang Portabel #

Masalah nyatanya: Windows memakai pemisah \ sedangkan Linux/macOS memakai / — path yang dihardcode patah saat skrip berpindah mesin. Mekanismenya: fullfile(bagian1, bagian2, ...) menggabungkan komponen path dengan pemisah yang benar untuk sistem operasi berjalan; filesep mengembalikan pemisah itu sendiri:

matlab
fprintf('filesep        : %s\n', filesep);
fprintf('fullfile contoh: %s\n', fullfile('data', 'a.csv'));

Output yang Dihasilkan (di Linux/macOS; di Windows filesep menjadi \):

text
filesep        : /
fullfile contoh: data/a.csv

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (filesep): karakter pemisah milik sistem — / di Linux, \ di Windows; gunakan untuk membangun path secara manual bila perlu.
  2. Baris 2 (fullfile): penggabungan berlapis yang benar secara otomatis — fullfile('data', 'arsip', 'b.csv') valid di semua platform.

exist, isfile, dan isfolder: Periksa Sebelum Bertindak #

Operasi berkas tanpa pemeriksaan awal berujung galat: membaca berkas yang tidak ada, atau menimpa folder yang sebenarnya masih dipakai. Mekanismenya: exist(nama, tipe) mengembalikan kode angka sesuai apa yang ditemukan, sedangkan pasangan modern isfile (R2017b+) dan isfolder (R2017b+) menjawab ya/tidak secara langsung:

Kode existArtiPadanan modern
0tidak adaisfile/isfolder = false
2berkasisfile = true
7folderisfolder = true
matlab
fprintf('folder data  ada (exist=7): %d\n', exist('data', 'dir'));
fprintf('isfile a.csv: %d\n', isfile(fullfile('data', 'a.csv')));

Output yang Dihasilkan:

text
folder data  ada (exist=7): 7
isfile a.csv: 1

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (exist('data', 'dir')): argumen 'dir' membatasi pencarian ke folder — hasil 7 membuktikan data/ sudah dibuat di bagian sebelumnya.
  2. Baris 2 (isfile): mengembalikan logical yang langsung bisa dipakai if — bentuk yang lebih ringkas dibanding membandingkan exist(...) == 2. Octave 10 juga menyediakan isfile/isfolder; untuk kompatibilitas versi lama, exist tetap jaring pengaman.

mkdir, copyfile, movefile, delete, dan rmdir #

Lima operasi dasar manajemen berkas membentuk siklus hidup proyek. Mekanismenya: mkdir membuat folder (gagal bila sudah ada), copyfile(sumber, tujuan) menyalin, movefile(sumber, tujuan) memindah sekaligus mengganti nama, delete menghapus berkas (mendukung wildcard), dan rmdir menghapus folder yang kosong:

matlab
mkdir('output');
copyfile(fullfile('data', 'a.csv'), fullfile('output', 'a.csv'));
fprintf('salinan di output: %d\n', exist(fullfile('output', 'a.csv'), 'file'));
movefile(fullfile('output', 'a.csv'), fullfile('data', 'a2.csv'));
fprintf('a2.csv di data   : %d\n', exist(fullfile('data', 'a2.csv'), 'file'));

Output yang Dihasilkan:

text
salinan di output: 2
a2.csv di data   : 2

Mari kita bedah baris-baris kode di atas:

  1. Baris 2 (copyfile): berkas a.csv kini hidup di dua tempat — salinan di output/, asli tetap di data/; exist = 2 memastikan salinan lahir.
  2. Baris 4 (movefile): salinan hilang dari output/ dan muncul sebagai a2.csv di data/ — satu panggilan untuk pindah + ganti nama.
  3. Bersih-bersih: delete(fullfile('data', '*.csv')) menghapus banyak berkas sekaligus lewat wildcard; rmdir('output') hanya berhasil bila folder kosong — MATLAB menolak menghapus folder yang masih berisi (gunakan rmdir(folder, 's') dengan sangat hati-hati untuk penghapusan rekursif).

Penelusuran Rekursif: Seluruh Berkas di Bawah Folder #

dir menyasar satu level saja. Untuk mengumpulkan semua berkas di bawah folder beserta subfoldernya, kita telusuri dengan tumpukan (stack): ambil satu folder dari tumpukan, daftar isinya, dorong subfolder kembali ke tumpukan, kumpulkan berkas:

matlab
mkdir(fullfile('data', 'arsip'));
copyfile(fullfile('data', 'b.csv'), fullfile('data', 'arsip', 'b.csv'));

tumpukan = {'data'};
daftar = {};
while ~isempty(tumpukan)
  folder = tumpukan{1};
  tumpukan(1) = [];
  L = dir(folder);
  for k = 1:numel(L)
    nama = L(k).name;
    if strcmp(nama, '.') || strcmp(nama, '..'), continue; end
    path = fullfile(folder, nama);
    if L(k).isdir
      tumpukan{end+1} = path;       % dorong subfolder ke tumpukan
    else
      daftar{end+1} = path;         % kumpulkan berkas
    end
  end
end
for k = 1:numel(daftar)
  fprintf('rekursif: %s\n', daftar{k});
end

Output yang Dihasilkan:

text
rekursif: data/a.csv
rekursif: data/a2.csv
rekursif: data/b.csv
rekursif: data/catatan.txt
rekursif: data/arsip/b.csv

Mari kita bedah baris-baris kode di atas:

  1. Baris 8-9 (folder = tumpukan{1}): elemen pertama diambil lalu dibuang — folder yang sama tidak diproses dua kali; loop berhenti saat tumpukan kosong.
  2. Baris 15-16 (tumpukan{end+1} = path): subfolder data/arsip didorong dan diproses pada putaran berikutnya — itulah “rekursi” versi iteratif, tanpa fungsi terpisah.
  3. Baris 17-18 (daftar{end+1} = path): hanya berkas yang dikumpulkan; hasil akhirnya daftar path lengkap yang siap diberikan ke readtable/textscan satu per satu.

Di MATLAB, pola recursive function (fungsi yang memanggil dirinya untuk tiap subfolder) memberikan hasil yang sama; versi tumpukan di sini dipilih karena berjalan identik di MATLAB dan Octave dalam satu script.

Praktik Proyek: data/ dan output/ #

Struktur minimal yang sehat untuk proyek analisis: data/ untuk berkas masukan (read-only — kode tidak pernah menulis ke sini), output/ untuk hasil, dan folder kerja untuk script. contoh.m pada bagian bawah halaman menerapkan siklus lengkapnya — membuat kedua folder, menulis berkas, meninjau dengan dir, menyalin, memindah, menelusuri rekursif, lalu membersihkan seluruh residue dengan delete + rmdir — sehingga script bisa dijalankan ulang berkali-kali dari kondisi bersih.

Ringkasan #

dir + wildcard memberi inventaris berkas berikut ukurannya; fullfile/filesep menjaga path tetap portabel lintas sistem operasi; exist/isfile/isfolder mencegah operasi buta; mkdir/copyfile/movefile/delete/rmdir membentuk siklus hidup folder proyek; dan penelusuran tumpukan mengumpulkan berkas lintas subfolder. Dengan berkas terkelola, satu tantangan terakhir tersisa: data yang lebih besar dari memori — chapter Bekerja dengan Dataset Besar.