Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {
- "cells": [
- {
- "cell_type": "raw",
- "metadata": {},
- "source": [
- "Пожалуйста, выполните небольшое задание. Напишите функцию — аналог команды du. Функция должна иметь один параметр — путь к каталогу — и возвращать сумму размеров всех файлов в этом каталоге, включая файлы во вложенных каталогах. Представьте, что вы запустили полученную функцию и команду du в одном и том же каталоге. Функция возвратила большее число, чем команда du. Почему так могло получиться? Как это исправить?"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Начнем с того, что \"размер файла\" и \"место, занимаемое файлом на диске\" - это в общем случае не одно и то же. \n",
- "\"Размером файла\" обычно называют собственно количество байт в файле. Пусть у нас есть файл `F.txt` размером FS = 15 КБ. \n",
- "\n",
- "Диск обычно разделен на блоки некоторого фиксированного размера; один и тот же блок не может быть \"поделен\" между двумя \"хозяевами\"-файлами. Пусть размер блока на нашем диске 4КБ.\n",
- "Наш файл F, очевидно, потребует минимум 4 блока на диске (т.к. `3 x 4 = 12 < 15`), т.е. при собственном размере в 15 КБ он займет не менее 16 КБ. Обозначим размер занятого места за DS.\n",
- "\n",
- "Теперь непосредственно к команде `du`. Вызов **`du F.txt`** без дополнительных ключей вернёт число `(DS / 1024)`, т.е. (округлённый) размер занятого места на диске в КБ. Собственный размер файла (в байтах) можно узнать с ключом `--apparent-size:` **`du --apparent-size F.txt`**. В результате должны получить число `FS`. \n",
- "\n",
- "Тонким моментом является работа с разреженными (`sparse`) файлами, у которых собственный (`apparent`) размер может быть больше, чем размер на диске. Это происходит от того, что разреженные файлы содержат участки с последоватальностями нулей, которые файловая система не записывает на диск, но сохраняет информацию о том, где они расположены в файле.\n",
- "\n",
- "Напишем на питоне (2.7) функцию, рекурсивно проходящуюся по всем вложенным директориям и возвращающую суммарный размер файлов. Пустая директория тоже занимает место на диске (размер 1 блока) . Библиотека `os` позволяет узнать как собственный размер файла, так и занимаемый размер на диске."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 241,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import os"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Напишем 2 функции: \n",
- "+ `getFileSize()` для определения размера файла\n",
- "+ `getDirSize()` для определения размера директории"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 242,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def getFileSize(filename):\n",
- " \n",
- " stats = os.stat(filename)\n",
- " \n",
- " # получение собственного размера файла\n",
- " fs = stats.st_size\n",
- " \n",
- " # получение занятого места на диске: (число блоков по 512 байт) х 512 \n",
- " fs_d = stats.st_blocks * 512\n",
- " \n",
- " # возвращаем размеры в байтах\n",
- " return (fs, fs_d) \n",
- "\n",
- "def getDirSize(path, ondisk=True):\n",
- " \n",
- " size = 0\n",
- " ondisk = int(ondisk)\n",
- " \n",
- " # размер пустой директории\n",
- " dirsize = 4096\n",
- " \n",
- " # цикл по всем поддиректориям\n",
- " for root, subdirs, files in os.walk(path):\n",
- " size_cur = dirsize + sum([getFileSize(root + '/' + f)[ondisk] for f in files])\n",
- " size += size_cur\n",
- " \n",
- " # возвращаем размер в байтах\n",
- " return size"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Проверим работу getFileSize() на тестовом документе:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 243,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(30, 4096)"
- ]
- },
- "execution_count": 243,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "getFileSize(\"/data/test_dir/test_txt\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 244,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "30\t/data/test_dir/test_txt\n",
- "4096\t/data/test_dir/test_txt\n"
- ]
- }
- ],
- "source": [
- "!du --apparent-size -B1 /data/test_dir/test_txt\n",
- "!du -B1 /data/test_dir/test_txt"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Проверим работу getDirSize() на тестовой директории:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 245,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "20538\n"
- ]
- }
- ],
- "source": [
- "print getDirSize(\"/data/test_dir/\", ondisk=False)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 246,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "4110\t/data/test_dir/test_subdir_1/test_subdir_3\r\n",
- "8220\t/data/test_dir/test_subdir_1\r\n",
- "4096\t/data/test_dir/test_subdir_2/.hidden_test_subdir\r\n",
- "8192\t/data/test_dir/test_subdir_2\r\n",
- "20538\t/data/test_dir/\r\n"
- ]
- }
- ],
- "source": [
- "!du --apparent-size -B1 /data/test_dir/"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 247,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "32768\n"
- ]
- }
- ],
- "source": [
- "print getDirSize(\"/data/test_dir/\", ondisk=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 248,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "8192\t/data/test_dir/test_subdir_1/test_subdir_3\r\n",
- "16384\t/data/test_dir/test_subdir_1\r\n",
- "4096\t/data/test_dir/test_subdir_2/.hidden_test_subdir\r\n",
- "8192\t/data/test_dir/test_subdir_2\r\n",
- "32768\t/data/test_dir/\r\n"
- ]
- }
- ],
- "source": [
- "!du -B1 /data/test_dir/"
- ]
- }
- ],
- "metadata": {
- "anaconda-cloud": {},
- "kernelspec": {
- "display_name": "Python [conda root]",
- "language": "python",
- "name": "conda-root-py"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 2
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython2",
- "version": "2.7.12"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement