Jaka jest koncepcja tworzenia pliku z zerowymi bajtami w systemie Linux?

32

Jeśli wykonam następujące czynności:

touch /tmp/test

a następnie wykonać

ls -la /tmp/

Widziałem testplik z 0 bajtami w katalogu.

Ale w jaki sposób system operacyjny obsługuje pojęcie 0 bajtów . Jeśli przedstawię to w sposób laicki:

0 Bajtów w ogóle nie ma pamięci, dlatego nic nie jest tworzone.

Tworzenie pliku musi, a przynajmniej powinno wymagać określonej pamięci, prawda?

Shan-Desai
źródło

Odpowiedzi:

63

Plik to (z grubsza) trzy osobne rzeczy:

  • „I-węzeł”, struktura metadanych, która śledzi, kto jest właścicielem pliku, uprawnień i listy bloków na dysku, które faktycznie zawierają dane.
  • Co najmniej jeden wpis katalogu (nazwy pliku) wskazujący ten i-węzeł
  • Same bloki danych

Podczas tworzenia pustego pliku tworzony jest tylko i-węzeł i pozycja katalogu wskazująca na ten i-węzeł. To samo dotyczy rzadkich plików ( dd if=/dev/null of=sparse_file bs=10M seek=1).

Podczas tworzenia dowiązań twardych do istniejącego pliku, po prostu tworzysz dodatkowe wpisy katalogu wskazujące na ten sam i-węzeł.

Upraszczam tutaj rzeczy, ale masz pomysł.

Xhienne
źródło
2
ładnie określone. promując jedną małą zagadkę za pomocą akapitu „hard-links”: jeśli ktoś tworzy hard-link do pustego pliku, który, jak twierdzisz, nie ma listy bloków, w jaki sposób ten hard-link może wskazywać na (tę samą) listę bloków które nie istnieją?
Theophrastus
4
@Theophrastus Dobra uwaga. Umożliwiłem uproszczenie. Właściwie między listą bloków a pozycjami katalogu istnieją metadane dotyczące pliku (do których odnosi się numer i-węzła) i które zawierają atrybuty pliku (właściciel, uprawnienia, ...) i atrybuty rozszerzone. Lista bloków jest tam. Tak więc wszystkie wpisy katalogu nie wskazują bezpośrednio na listę bloków (sposób FAT), ale na metadane.
xhienne
6
Powinny być trzy osobne rzeczy: Lista bloków zawierających dane; same bloki ; oraz wpis do katalogu (lub wpisów) wskazujący na listę bloków.
Wildcard
@Wildcard Przesłałem edycję, aby uczynić ją trzema rzeczami, i nazwałem i-węzeł jego nazwą. Zarówno i-węzeł, jak i katalogi są metadanymi; ale są to różnego rodzaju metadane. Plik zawsze ma jeden i-węzeł i co najmniej jedną pozycję katalogu. Ten i-węzeł może zawierać pustą listę bloków danych.
Monty Harder
1
@Wildcard Nawet jeśli jesteś początkującym, ważne jest zrozumienie różnicy między i-węzłem a katalogiem. Gdy ktoś zmieni uprawnienia / własność „nazwy katalogu” i pomyśli, że inne łącza do tego samego i-węzła zachowają stare uprawnienia / własność, może się zdarzyć coś bardzo złego. Nie musimy zagłębiać się w szczegóły, w jaki sposób i-węzły odnoszą się do bloków bezpośrednich, bloków pośrednich, bloków podwójnie i potrójnie pośrednich, aby uzyskać listę bloków. Lub że lista może być pusta.
Monty Harder
24

touchutworzy i- węzeł i ls -ilub statwyświetli informacje o i-węzle:

$ touch test
$ ls -i test
28971114 test
$ stat test
  File: ‘test’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fc01h/64513d    Inode: 28971114    Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/1000)   Gid: ( 1000/1000)
Access: 2017-03-28 17:38:07.221131925 +0200
Modify: 2017-03-28 17:38:07.221131925 +0200
Change: 2017-03-28 17:38:07.221131925 +0200
 Birth: -

Zauważ, że testużywa 0 bloków. Do przechowywania wyświetlanych danych i-węzeł wykorzystuje niektóre bajty. Te bajty są przechowywane w tabeli i-węzłów. Spójrz na stronę ext2, aby zobaczyć przykład struktury i-węzła .

CTX
źródło
19

ls(lub cóż, stat(2)wywołanie systemowe) informuje o rozmiarze zawartości pliku. To, ile miejsca potrzebuje system plików na prowadzenie ksiąg rachunkowych, nie jest częścią tego i, jako szczegół implementacji, nie jest czymś, o czym programy powinny dbać, a nawet wiedzieć. Widoczne szczegóły implementacji sprawiłyby, że abstrakcja systemu plików byłaby mniej użyteczna.

ilkkachu
źródło
9

Sam plik nie zajmuje żadnej przestrzeni, ale system plików, przechowując nazwę pliku, lokalizację, prawa dostępu do niego i tym podobne.

Patrick Bucher
źródło
4
Jeśli spojrzysz na miejsce zajmowane przez pozycję katalogu, jeśli masz katalog zawierający tysiąc plików o rozmiarze 0 bajtów, katalog będzie większy niż pozycja katalogu, która zawiera tylko 2 ogromne pliki.
Mark Stewart
2
argumenty za wspomnieniem, że plik jest abstrakcyjnym pojęciem, które nie jest ściśle powiązane z jego fizyczną reprezentacją np. na dysku.
Florian Castellane
5

Prosta odpowiedź: Ponieważ tak jest zdefiniowane.

Dłuższa odpowiedź: zdefiniowano w ten sposób, ponieważ niektóre operacje są koncepcyjnie prostsze:

  • Jeśli plik zawiera 20 liter „A” i usuniesz wszystkie litery „A”, plik będzie krótszy o 20 bajtów. Ta sama operacja na pliku składającym się tylko z „AAAAAAAAAAAAAAAAAAAA” musiałaby dotyczyć specjalnego przypadku znikania pliku.
  • Praktycznie usunięcie ostatniego wiersza pliku tekstowego wymagałoby specjalnego wpisania.
  • Edytory tekstu, którzy regularnie wykonują kopię zapasową, potrzebowaliby specjalnego kodu, aby poradzić sobie z sytuacją, w której użytkownik może usunąć ostatni wiersz, iść na lunch, a następnie wrócić i dodać kolejny wiersz. Dalsze komplikacje pojawiają się, jeśli niektórzy inni użytkownicy utworzyli plik o tej nazwie w międzyczasie.

Możesz zrobić więcej rzeczy: * Pliki dziennika błędów są zwykle tworzone jako puste, do wypełnienia tylko i tylko w przypadku wystąpienia błędu. * Aby dowiedzieć się, ile błędów się wydarzyło, policzysz liczbę wierszy w plikach dziennika. Jeśli plik dziennika jest pusty, liczba błędów wynosi zero, co ma idealny sens. * Czasami widzisz pliki, w których cały odpowiedni tekst znajduje się w nazwie pliku, np this-is-the-logging-directory. Zapobiega to nadmiernym administratorom usuwania pustych katalogów po instalacji, a także zapobiega błędom, w których program lub użytkownik przypadkowo tworzy plik, w którym program chciałby później zobaczyć katalog. gitProgramu (i inni) mają tendencję do ignorowania pustych katalogów, a jeśli projekt / administrator / użytkownik chce mieć zapis, że katalog istnieje, mimo że nie ma przydatnych treści (jeszcze), można zobaczyć pusty plik o nazwieemptylub empty.directory.

Żadne operacje nie stają się bardziej skomplikowane:

  • Łączenie plików: jest to po prostu brak operacji z pustym plikiem.
  • Wyszukiwanie ciągu w pliku: jest to objęte standardowym przypadkiem „jeśli plik jest krótszy niż wyszukiwane hasło, nie może zawierać wyszukiwanego hasła”.
  • Czytanie z pliku: programy muszą poradzić sobie z trafieniem na koniec pliku, zanim otrzymają to, czego się spodziewali, więc znowu przypadek pliku o zerowej długości nie wymaga dodatkowego myślenia dla programisty: po prostu uderzy w koniec -plik od samego początku.

W przypadku plików aspekt „istnieje gdzieś plik nagrany” (nazwa i-węzła i / lub nazwa pliku) jest najważniejszy z powyższych rozważań, ale systemy plików nie zrobiłyby tego, gdyby puste pliki były bezużyteczne.

Zasadniczo wszystkie powyższe powody oprócz tych związanych z nazwami plików dotyczą sekwencji. W szczególności ciągi, które są ciągami znaków: Ciągi o zerowej długości są powszechne w programach. Ciągi są zwykle niedozwolone na poziomie użytkownika, jeśli nie mają sensu: nazwa pliku jest ciągiem, a większość systemów plików nie zezwala na pusty ciąg jako nazwę pliku; wewnętrznie, podczas tworzenia nazw plików z fragmentów, program może mieć pusty ciąg jako jeden z fragmentów.

toolforger
źródło
1

Używając najprostszej analogii:

Porównajmy plik z, powiedzmy, szklanką wody.

„touch / tmp / test” bardzo przypomina tworzenie pustej szklanki bez wody. Szklanka jest pusta, więc jej rozmiar wynosi zero. Ale szkło istnieje.

W mowie systemu plików szkło jest meta-danymi, podczas gdy zawartość szkła jest danymi. Metadane zawierają różnego rodzaju rzeczy, jak wspomniano w poprzednich postach.

Przydatne mogą być pliki o zerowej wielkości. Jednym z przykładów jest użycie ich jako bułki tartej, gdzie samo jego istnienie można wykorzystać do wskazania pewnego rodzaju stanu (tj. Jeśli plik istnieje: to zrób coś; jeśli nie: zignoruj).

El Stepherino
źródło
0

Pomyśl o tym w ten sposób: powiedz, że program śledzi zapytania SQL wysłane na twój serwer. Program chce wskazać, że rejestruje żądania do zwykłego pliku tekstowego, ale żadne żądania nie zostały jeszcze zarejestrowane. Jak to powinno wyglądać? Twierdziłbym, że powinien to być plik o zerowej wielkości /var/log/acme-sql-server/queries.log. W ten sposób możesz dowiedzieć się, kiedy rozpoczęło się rejestrowanie (czas utworzenia pliku), kiedy było ono ostatnio aktualizowane (tj. Kiedy zostało utworzone), ile zapytań zostało zarejestrowanych (liczba nowych wierszy w pliku = 0) i kto rejestruje (Acme SQL Server). W takich przypadkach przydatna jest koncepcja pustego pliku, który mimo to istnieje w określonej lokalizacji.

Gauraw
źródło