Spis treści
- Wprowadzenie
- File System Access API
- Działająca aplikacja na Github Pages
- Pełen kod aplikacji na Github
- Podsumowanie
Wprowadzenie
Ukazał się już na portalu post o File System Access API:
I w momencie pisania tamtego artykułu wydawało się, że zostanie ono raczej tylko ciekawostką zaimplementowaną tylko w Chrome.
W lutym 2022 tego roku okazało się, że ekosystem Apple również dostanie to API i będzie w nim wspierane. W mocno ograniczonej formie, jako Origin Private File System – ale jednak.
Warto więc odświeżyć temat, pokazując jak napisać mega uproszczoną przeglądarkę plików, która pozwoli otworzyć folder oraz wyświetlić zagnieżdżone w nim foldery oraz pliki.
Zapraszam do czytania 🙂
File System Access API
Krótkie wtrącenie o Origin Private File System
OPFS różni się od implementacji desktopowej. Wersja desktopowa pozwala czytać rzeczywiste pliki i foldery na dysku twardym użytkownika komputera – stąd straszne ostrzeżenie w momencie gdy aplikacja pyta o uprawienia 🙂

OPFS działa w nieco inny sposób – mamy możliwość tworzenia i odczytywania plików i katalogów w ramach jednej domeny i nie ma gwarancji, w jaki sposób przeglądarka będzie nasze pliki reprezentować – mogą być one „bezpośrednio” na dysku bądź też w bazie danych.
Przykładowo – plików utworzonych w ramach domeny https://www.wp.pl/ nie da się odczytać w ramach https://frontcave.pl/
Jeśli chcesz sprawdzić jak działa OPFS, możesz wejść np z iPhone na przykład implementacji:
https://radek-anuszewski.github.io/file-system-acces-api-ios-mac/
Link był fragmentem newslettera który wysyłam co dwa tygodnie liście mailowej, na którą możesz zapisać się tutaj (dostaniesz też ciekawy dokument dotyczący Reacta):
Stworzenie prostej przeglądarki plików tekstowych
Założenia
Przeglądarka wczyta pliki tekstowe i foldery z wybranego katalogu oraz umożliwi wyświetlenie zawartości plików tekstowych po kliknięciu.
Więc implementacja będzie zawierać:
- Wczytanie zagnieżdżonych plików i folderów X poziomów w dół
- Odfiltrowanie plików innych niż z rozszerzeniem txt
- Wyświetlanie zawartości pliku po kliknięciu
Implementacja
Akcję otwarcia pickera z folderami podepniemy pod przycisk:
document.querySelector('#selectMain').addEventListener('click', async () => {
data = {};
const mainDirectoryHandle = await window.showDirectoryPicker();
await readElements(mainDirectoryHandle, data, 0);
drawElements(data);
});
Funkcja showDirectoryPicker spowoduje otwarcie pickera z możliwością wyboru katalogu.
Zwrócony zostanie handler typu FileSystemDirectoryHandle, który w metodzie entries zwróci nam handlery do zawartych w nim folderów i plików.
Skorzysta z tej metody funkcja readElements:
const readElements = async (handle, elData, level, maxLevel = 5) => {
if (level >= maxLevel) {
return;
}
for await (const [elName, elHandle] of handle.entries()) {
if (elHandle.kind === 'directory' || elHandle.name.endsWith('.txt')) {
elData[elName] = {
name: elName,
kind: elHandle.kind,
handle: elHandle,
...(elHandle.kind === 'directory' ? {data: {}} : {}),
...(elHandle.kind === 'file' ? {file: await elHandle.getFile()} : {}),
}
if (elHandle.kind === 'directory') {
await readElements(elHandle, elData[elName].data, level + 1);
}
}
}
}
Wewnątrz funkcji odczytujemy zawartość handlera i wpisujemy ją do obiektu – jeśli trafimy na folder tworzymy nowy zagnieżdżony obiekt, do którego rekurencyjnie dopiszemy zawartość tego folderu – parametr maxLevel o wartości 5 oznacza, że zejdziemy maksymalnie 5 poziomów w dół.
Jeśli trafimy na plik, od razu pobierzemy go za pomocą metody getFile.
Jak pewnie udało Ci się zauważyć, za pomocą ifa odfiltrowywujemy wszystko, co nie jest katalogiem bądź plikiem z rozszerzeniem txt. W dalszej części artykułu znajdziesz link do działającej aplikacji w Github Pages – najlepiej stwórz sobie zagnieżdżoną strukturę folderów z plikami txt, by lepiej móc zobaczyć działanie aplikacji.
W momencie gdy mamy już obiekt z danymi, na jego podstawie możemy stworzyć DOM naszej przeglądarki plików za pomocą metody drawElements:
const drawElements = (elData, indentText = '') => {
for (const key in elData) {
if (elData.hasOwnProperty(key)) {
const el = elData[key];
const directory = el.kind === 'directory';
const div = document.createElement('div');
div.innerHTML = `${indentText}${directory ? `<strong>${el.name}</strong>` : el.name}`;
div.style.padding = '5px 0';
if (el.kind === 'file') {
div.style.cursor = 'pointer';
div.onclick = async () => document.querySelector('#fileText').innerHTML = await el.file.text();
}
document.querySelector('#elements').appendChild(div);
if (directory) {
drawElements(el.data, indentText + '--');
}
}
}
};
Struktura HTML jest płaska, zagnieżdżenie folderów pokazywane jest za pomocą ilości znaków ==. Jeżeli natrafiamy na plik, podpinamy pod renderowany element metodę, która z pliku za pomocą metody text wyciąga zawartość tekstową którą następnie można wyświetlić. Foldery odróżniają się od plików tym, że są pogrubione:

Działająca aplikacja na Github Pages
Działającą aplikację znajdziesz pod adresem:
https://radek-anuszewski.github.io/simple-file-browser/
Dobrze testować ją na zagnieżdżonych folderach z kilkoma plikami tekstowymi, wtedy najlepiej widać że możemy wczytywać pliki i foldery niżej głębiej niż tylko w folderze głównym.
Pełen kod aplikacji na Github
https://github.com/radek-anuszewski/simple-file-browser
Podsumowanie
Choć wsparcie tylko dla OPFS w ekosystemie Apple nie wydaje się być mocno użyteczne, pamiętajmy że to kolejny krok w rozszerzeniu wsparcia. Stąd warto pamiętać o File System Access API i co jakiś czas odświeżać wiedzę o nim, ponieważ widać że twórcy przeglądarek coraz bardziej się do niego przekonują.

