Форум программистов, компьютерный форум, киберфорум
Языки JVM
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.50/14: Рейтинг темы: голосов - 14, средняя оценка - 4.50
21 / 21 / 1
Регистрация: 24.07.2013
Сообщений: 121
1

Clojure Задать директорию и вывести список файлов и их размеры

04.04.2014, 23:21. Показов 2880. Ответов 29
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, дорогие форумчане и гости!
Собственно, задачу Я описал в заголовке.
Интересует: какая функция Lisp возвращает список файлов в заданной директории и чтобы с каждого из них(файлов) можно было вытащить информацию о его размере на диске?
Как найти размер файла Я примерно знаю:
Lisp
1
2
3
(setq somefile (open "C://file/name.txt"))
(file-length somefile)
(close somefile)
Помогите, пожалуйста!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.04.2014, 23:21
Ответы с готовыми решениями:

Размеры файлов в список
Доброго времени суток. Подскажите пожалуйста вот что: Есть у меня папка с файлами, хочу написать...

Нужно вывести на экран информацию про системную директорию и директорию windows
Помогите плз!Нужно написать прогу которая выводит на екран такую инфу:Computer name,user...

Вывести имена и размеры всех файлов в заданном каталоге и упорядочить их
Выведите на экран имена и размеры всех файлов в заданном каталоге. Отсортируйте • по дате...

Модуль DOS. Вывести на экран размеры всех файлов, находящихся в текущем каталоге
Вывести на экран размеры всех файлов, находящихся в текущем каталоге, имена которых начинаются на...

29
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
04.04.2014, 23:35 2
Mypowerfulbrain, cl-fad
1
Модератор
Эксперт функциональных языков программированияЭксперт Python
36847 / 20407 / 4235
Регистрация: 12.02.2012
Сообщений: 33,776
Записей в блоге: 13
04.04.2014, 23:45 3
В HomeLisp - три строчки:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(defun flist (aDir)
  (let ((tmp (sysdir (strcat aDir "\*.*") &HFF)))
    (iter (for i in tmp) (prints i) (prints " ") (printsline (sysgetattr i))))) 
 
==> flist
 
(flist (sysHome))
 
graphs-06.lsp (7232 "18.11.2013 20:35:16" &H20)
Blobs.bas (109118 "20.03.2012 12:24:34" &H20)
weblisp.txt (41 "07.03.2014 18:33:24" &H20)
lst-lv.lsp (4940 "18.03.2013 19:45:02" &H20)
CompLisp.bas (14997 "20.11.2008 20:08:04" &H20)
qqqqqq.txt (1543 "04.04.2012 12:47:46" &H20)
d-test.exe (298480 "23.01.2011 13:20:30" &H20)
Files.bas (39372 "19.09.2013 11:07:14" &H20)
globaldef.bas (61 "12.03.2009 21:37:20" &H20)
globals.bas (1237 "17.07.2011 13:13:26" &H20)
3
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
05.04.2014, 02:41 4
Mypowerfulbrain, ваш код нехорош. Файлы следует открывать с помощью with-open-file, это защищает от последствий ошибок ввода/вывода. Файлы - это внешний мир, всегда надо быть осторожным.

Думается, список файлов в директории лучше всего получать с помощью библиотеки uiop.

Lisp
1
2
3
4
5
6
7
(defun file-size (filespec)
  (with-open-file (f filespec :direction :input)
    (file-length f)))
;; REPL
CL-USER> (loop for f in (uiop/filesystem:directory-files "~/test/") collect (list (namestring f) (file-size f)))
(("/home/me/test/test1.txt" 6)
 ("/home/me/test/test2.txt" 13))
Правда, file-length мутно в стандарте описана, и остаётся надеяться, что ваша реализация лиспа на вашей платформе работает так, как вы ожидаете. Другие подходы - читать файл побайтно и считать байты или обратиться к ОС и узнать размер файла. Последний метод, ясное дело, ещё от ОС зависит.

uiop - это часть ASDF3, она будет всегда и везде, и люди стараются на самом деле, должно получиться максимально переносимо между системами и реализациями. То есть uiop - это завтрашний день. cl-fad - вчерашний. Сегодня - ?
3
Модератор
Эксперт функциональных языков программированияЭксперт Python
36847 / 20407 / 4235
Регистрация: 12.02.2012
Сообщений: 33,776
Записей в блоге: 13
05.04.2014, 07:16 5
Цитата Сообщение от helter Посмотреть сообщение
Другие подходы - читать файл побайтно и считать байты или обратиться к ОС и узнать размер файла.
- считать байты - это убийство... Длина файла во всех файловых системах хранится в элементе оглавления.
3
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
05.04.2014, 15:30 6
Цитата Сообщение от Catstail Посмотреть сообщение
считать байты - это убийство
Наверно, file-length так и делает, иначе зачем ему дают открытый поток. Кстати, вот обсуждение, инициированное небезызвестным Seib'l-ем: https://groups.google.com/foru... L0qGLZcP0J

"Все файловые системы" в стандарт не внесёшь. Жалко, однако, что в uiop, кажется, нет ничего про размер файла.
1
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
05.04.2014, 16:43 7
Цитата Сообщение от Catstail Посмотреть сообщение
считать байты - это убийство
почему?

Добавлено через 22 минуты
Bash
1
2
3
4
# dd if=/dev/zero of=/home/sun/10gb.file count=10 bs=1G
10+0 записей получено
10+0 записей отправлено
 скопировано 10737418240 байт (11 GB), 327,92 c, 32,7 MB/c
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
INSOMNIA> (time 
           (progn
             (setf s (open "/home/sun/10gb.file"))
             (format t "~A" (file-length s))
             (close s)))
10737418240
Evaluation took:
  0.000 seconds of real time
  0.001000 seconds of total run time (0.000000 user, 0.001000 system)
  100.00% CPU
  1,183,464 processor cycles
  31,584 bytes consed
  
T
Добавлено через 25 минут
и ещё один убийственный тест:
Bash
1
2
thumbs # ls | wc -l
26420
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BFTV> (defparameter *ldir*
        (list-directory "thumbs"))
*LDIR*
BFTV> (length *ldir*)
26420
BFTV> (time
       (loop for a in *ldir*
          summing
            (with-open-file (s a)
              (file-length s))))
Evaluation took:
  1.985 seconds of real time
  1.971701 seconds of total run time (1.448780 user, 0.522921 system)
  [ Run times consist of 0.035 seconds GC time, and 1.937 seconds non-GC time. ]
  99.35% CPU
  4,765,153,734 processor cycles
  208,934,040 bytes consed
  
226489982
Добавлено через 2 минуты
Цитата Сообщение от helter Посмотреть сообщение
cl-fad - вчерашний
блин, живу вчерашним днём.... =)
3
Модератор
Эксперт функциональных языков программированияЭксперт Python
36847 / 20407 / 4235
Регистрация: 12.02.2012
Сообщений: 33,776
Записей в блоге: 13
05.04.2014, 17:41 8
Цитата Сообщение от transformator.t Посмотреть сообщение
почему?
- долго...
Цитата Сообщение от helter Посмотреть сообщение
Наверно, file-length так и делает
- не думаю. И в Win и в Nix (даже в Dos) длина файла хранится в элементе оглавления.
2
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
05.04.2014, 17:55 9
Цитата Сообщение от Catstail Посмотреть сообщение
- долго...
ну где же долго, 26420 файлов - 1.985 seconds
3
Модератор
Эксперт функциональных языков программированияЭксперт Python
36847 / 20407 / 4235
Регистрация: 12.02.2012
Сообщений: 33,776
Записей в блоге: 13
05.04.2014, 20:30 10
transformator.t, согласен, убедили!

Добавлено через 1 минуту
Но в Win все это можно сделать и без открытия (open)

Добавлено через 2 минуты
Полагаю, кстати, что и в Вашем примере не происходит подсчета байтов. Длина берется из оглавления. Просто в Win это можно сделать и без открытия файла.
2
Заблокирован
05.04.2014, 20:37 11
Вот так примерно может выглядеть подобный код на автолисп
Lisp
1
2
3
4
5
6
7
8
(defun file_info (dir pat)
  (mapcar '(lambda (x) (cons x (vl-file-size (strcat dir x))))
      (vl-directory-files dir pat 1)
  )
)
 
(file_info "C:/HomeLisp/" "*.exe")
==> (("ARJ32.EXE" . 262573) ("clisp.exe" . 11776) ("homelispide.exe" . 500736) ("HomeLispLib.exe" . 1576960) ("PKZIP.EXE" . 42166) ("starter.exe" . 20480) ("vbUnsetup.exe" . 32768) ("wlisp.exe" . 13824))
5
Модератор
Эксперт функциональных языков программированияЭксперт Python
36847 / 20407 / 4235
Регистрация: 12.02.2012
Сообщений: 33,776
Записей в блоге: 13
05.04.2014, 20:44 12
Цитата Сообщение от ur_naz Посмотреть сообщение
vl-file-size
- о чем я и говорю... Открывать-то зачем?
1
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
05.04.2014, 21:20 13
Цитата Сообщение от Catstail Посмотреть сообщение
Открывать-то зачем?
В стандарте Common Lisp предусмотрена функция file-length, которая принимает поток. Открывать надо. Только мы не знаем, кто как реализует эту функцию. Можно представить реализацию, в которой file-length не читает файл, а обращается к ОС.
3
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
05.04.2014, 22:30 14
helter, если взять микроскоп, то для linux:
Bash
1
2
# ls -l etc-last.xz 
-rw-r--r-- 1 root root 1220368 дек 10 10:45 etc-last.xz
Bash
1
2
# strace -s 512 ls -l etc-last.xz 2>&1 | grep lstat
lstat("etc-last.xz", {st_mode=S_IFREG|0644, st_size=1220368, ...}) = 0
Добавлено через 50 минут
точки расставлены:
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
INSOMNIA> (defparameter
              *thumbs*
            (list-directory 
             "thumbs/"))
*THUMBS*
INSOMNIA> (length *thumbs*)
26466
INSOMNIA> (time
           (loop for a in *thumbs*
              summing
                (with-open-file (s a)
                  (file-length s))))
Evaluation took:
  1.655 seconds of real time
  1.631000 seconds of total run time (1.289000 user, 0.342000 system)
  [ Run times consist of 0.088 seconds GC time, and 1.543 seconds non-GC time. ]
  98.55% CPU
  3,960,208,040 processor cycles
  315,990,336 bytes consed
  
226832166
INSOMNIA> (time
           (loop for a in *thumbs*
              summing
                (progn
                  (setf file (sb-posix:stat a))
                  (sb-posix:stat-size file))))
 
Evaluation took:
  0.237 seconds of real time
  0.237000 seconds of total run time (0.193000 user, 0.044000 system)
  100.00% CPU
  567,675,279 processor cycles
  67,654,976 bytes consed
  
226832166
5
505 / 511 / 42
Регистрация: 12.12.2013
Сообщений: 484
05.04.2014, 22:59 15
На Clojure как то так:
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(ns learn-clojure.example
  (:import [java.io File FilenameFilter]))
 
(defn file-info [^String path ^String ext]
  (let [p (File. path)
        f-ext (reify FilenameFilter (accept [this path name]
                                      (.endsWith name ext)))]
    (map list
         (.list p f-ext)
         (map #(.length %) (.listFiles p f-ext)))))
 
(in-ns 'learn-clojure.example)
;; => #<Namespace learn-clojure.example>
 
(file-info "C:/Windows" ".exe")
;; => (("bfsvc.exe" 71168) ("explorer.exe" 2871808) ("fveupdate.exe" 15360) ("HelpPane.exe" 733696) ("hh.exe" 16896) ("notepad.exe" 193536) ("py.exe" 93696) ("pyw.exe" 94208) ("regedit.exe" 427008) ("splwow64.exe" 67072) ("twunk_16.exe" 49680) ("twunk_32.exe" 31232) ("winhlp32.exe" 9728) ("write.exe" 10240))
3
Модератор
Эксперт функциональных языков программированияЭксперт Python
36847 / 20407 / 4235
Регистрация: 12.02.2012
Сообщений: 33,776
Записей в блоге: 13
06.04.2014, 09:41 16
Цитата Сообщение от helter Посмотреть сообщение
В стандарте Common Lisp предусмотрена функция file-length, которая принимает поток. Открывать надо. Только мы не знаем, кто как реализует эту функцию. Можно представить реализацию, в которой file-length не читает файл, а обращается к ОС.
- стандарты создают люди, а не боги. Людям свойственно ошибаться. Собственно, ситуация, при которой созданный и утвержденный стандарт оказывается крайне неудобным, встречается очень часто (и в IP, и в HHTP, и в HTML). И что, быть рабом стандарта?

Вообще в любой ОС операция "open" одна из самых медленных. Поэтому, если в стандарте CL, единственный способ узнать длину файла - это его открыть, то стандарт... неправ.

Другое дело, что о длине файла можно говорить в двух случаях: длина неоткрытого файла (т.е. длина набора данных на носителе, о чем мы и говорим) и длина этого набора у активного файла (с которым выполнялись операции), в этом случае логично обращаться к файлу через его хэндл...

Даже в VB/VBA есть две функции: 1) FileLen(String) - длина без открытия; 2) Lof(integer) - длина открытого.
1
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
06.04.2014, 11:10 17
никаких заголовков не видно:
Bash
1
2
3
 $ touch test.file; echo 'a' > test.file; hexdump -C test.file
00000000  61 0a                                             |a.|
00000002
1
21 / 21 / 1
Регистрация: 24.07.2013
Сообщений: 121
06.04.2014, 11:49  [ТС] 18
Люди, всем большое спасибо. Сейчас у меня практически нет времени появляться на форуме и пробовать советы, но Я это сделаю в ближайшее время.
0
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
06.04.2014, 13:26 19
ещё раз глянул:
Bash
1
2
3
4
$ cat test.file
a b c d e f
 
m n v x z q
Bash
1
2
$ ls test.file -l
-rw-r--r-- 1 sun sun 25 апр  6 16:17 test.file
размер 25 байт
Bash
1
2
3
4
 $ hexdump -C test.file 
00000000  61 20 62 20 63 20 64 20  65 20 66 0a 0a 6d 20 6e  |a b c d e f..m n|
00000010  20 76 20 78 20 7a 20 71  0a                       | v x z q.|
00000019
Lisp
1
2
INSOMNIA> (format t "~16R" 25)
19
00000019 - это размер, ок, но он расположен не в голове...
наверное нужно покурить спецификацию фс
2
Модератор
Эксперт функциональных языков программированияЭксперт Python
36847 / 20407 / 4235
Регистрация: 12.02.2012
Сообщений: 33,776
Записей в блоге: 13
06.04.2014, 13:48 20
Цитата Сообщение от transformator.t Посмотреть сообщение
наверное нужно покурить спецификацию фс
- несомненно.

Добавлено через 5 минут
На самом деле, после некоторого размышления, я пришел к выводу, что можно примирить реализацию стандарта CL и здравый смысл. Достаточно предположить, что реализация open на самом деле открывает файл при первой операции ввода/вывода. Тогда можно "открыть" поток и получить длину на диске (из оглавления) без реального открытия. Это будет выполняться достаточно быстро. Экономится одна функция и модель становится стройнее (все - через поток).
2
06.04.2014, 13:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.04.2014, 13:48
Помогаю со студенческими работами здесь

FTP: получение списка файлов из потока. Как вывести список файлов из директории?
доброго времени суток. пытаюсь написать свой FTP-клиент. отправил серверу команду LIST, и в...

Установка в выбранную директорию 2 файлов и автоматическое занесение файлов реестра
Здравствуйте. Мне нужно чтобы моя прога установила в выбранной директорию 2 файла. И у меня есть...

Как правильно задать директорию?
$config = base_url('/assets/'); не загружаются картинки

Вывести на экран размеры типов и размеры указателей на объекты
Составить программу, которая позволяет вычислить и вывести на экран размеры типов и размеры...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru