2017-03-02 1 views
1

Je travaille sur un système qui ne supporte pas lua File System Library. Donc je dois faire mon propre itérateur de répertoire qui me donne la liste des fichiers avec le chemin complet du format particulier.lua Custom Directory Iterator

Le système possède une API que nous pouvons définir pour le chemin d'accès au répertoire et une autre API pour obtenir la liste des fichiers dans ce répertoire au format table lua.

L'API: FileSetDir() définit le répertoire pour obtenir la liste des fichiers. L'API: FileList() donne la table de liste de fichiers du répertoire que nous avons défini à l'aide de l'API: FileSetDir(). Par exemple, considérez la structure de répertoires suivante:

Movies/3d Movies/Avatar/Avatar.mp4 
Movies/3d Movies/Avengers/Avengers.mkv 
Movies/3d Movies/ironman.mp4 
Movies/Horor/Ring/Ring.avi 
Movies/Horor/A Nightmare On Elm Street/A Nightmare On Elm Street.iso 
Movies/Barfi.mkv 

Mon code ..

RootDirList1 = {} 
RootDirList = {} 
finalpath={} 


function SetDIR(v) 
    if v=="" then 
     RootDir = '/mnt/media/net/192.168.1.40_usbshare1/Movies/' 
    else 
     RootDir = '/mnt/media/net/192.168.1.40_usbshare1/Movies/'..v 
    end 
    API:FileSetDir (RootDir) 
    RootDirList1 = API:FileList() 
    CheckDirectory() 
end 

function CheckDirectory() 
    for i,v in pairs(RootDirList1) do 
     local RootDir = '/mnt/media/net/192.168.1.40_usbshare1/Movies/'..v 
     API:FileSetDir (RootDir) 
     local RootDirList = API:FileList() 
     if RootDirList == nil then 
      print(v) 
      print("Not Directory") 
      if string.find(v,"%.mkv$") or string.find(v,"%.mp4$") then 
       finalpath[#finalpath+1] =RootDir.."/"..t 
      print(RootDir.."/"..t) 

      end 
     else  
      CheckDirectory(v) 
     end 
    end 
end 

SetDIR("") 

Le code me donne une erreur avec "débordement de la pile". Le SetDIR définit le répertoire avec API: FileSetDir (RootDir) et obtenir la liste des fichiers dans la table RootDirList1. alors j'appelle la fonction CheckDirectory() ici j'exécute une boucle pour la table RootDirList1 si l'entrée de la table est le fichier où elle sera stockée dans la table finalpath. Si l'entrée de la table est Directory, elle appelle SetDIR pour obtenir la liste des fichiers dans ce répertoire.

Je sais que mon approche est fausse de faire de ce travail une idée brillante sera grandement appréciée.

+1

chèque excès "ou" en chaîne "si string.find (v," %. Mkv $ ") ou string.find (v," %. Mp4 $ ") ou alors" oh –

+0

qui était un typo le code original n'a pas cela. –

+2

function CheckDirectory() - appel sans fin sans paramètres –

Répondre

2

débordement de la pile (heh) signifie que, eh bien, la pile déborde - il est plein. Une pile est essentiellement une région de mémoire qui ressemble littéralement à une pile d'IRL: vous pouvez placer quelque chose dessus (pousser) ou la récupérer (pop).

Lua a plus d'une pile. L'important ici est la pile d'appels : lorsque vous appelez une fonction, vous lui poussez une valeur (où reprendre après son retour). Il est limité de sorte que vous ne pouvez pas consommer de mémoire infinie. Donc, en gros, votre code provoque une récursion infinie. Il s'appelle et ne progresse pas, donc il remplit juste la mémoire et ne fait rien.

Cela dit, votre erreur était dans cette ligne:

local RootDir = '/mnt/media/net/192.168.1.40_usbshare1/Movies/'..v 

Vous essayez de la liste récursive, non? Ce n'est pas récursif du tout. Cette ligne suppose que le fichier est dans le dossier racine, "Movies", qui génère une récursion infinie, car il vérifie le même dossier encore et encore, encore et encore, encore et encore. Vous devriez plutôt ajouter à l'actuel RootDir. Je pense que CheckDirectory(v) joue également un rôle dans ce. Qu'est ce que c'est censé vouloir dire? CheckDirectory n'a pas d'arguments! (merci Egor de l'avoir signalé)

Ci-dessous, j'ai refaçonné votre code, en changeant complètement l'opération pour être plus efficace, et en corrigeant les problèmes d'identification.

function CheckDirectory(dir) 
    local result = {} 

    -- set directory to dir, then list it 
    API:FileSetDir(dir) 
    local list = API:FileList() 

    for i, v in pairs(list) do 
     API:FileSetDir(dir .. v .. "/") -- fixed! 

     local clist = API:FileList() 

     -- don't compare to nil. Just use 'not clist'. 
     -- And besides, we have an else, so I inverted everything 
     -- and collapsed the else .. if into elseif. 
     if clist then 
      for i, v in ipairs(CheckDirectory(dir .. v .. "/")) do 
       table.insert(result, v) 
      end 
     elseif string.find(v, "%.mkv$") or string.find(v, "%.mp4$") then 
      table.insert(result, dir .. v) 
      print(dir .. v) -- remove this line if you don't want to print 
     end 
    end 

    return result 
end 

local files = CheckDirectory('/mnt/media/net/192.168.1.40_usbshare1/Movies/') 
+0

Wow fonctionne Tranquillement bien. Pas de hiccup CPU. seul problème est tout le chemin a le même nom de film à la fin. "Sous l'Antarctique - Full Documentary HD.mp4" –

+0

/mnt/media/net/192.168.1.40_usbshare2/Movies/3D Movies/Yogi Bear 3D/Sous l'Antarctique - Documentaire complet HD.mp4/mnt/media/net/192.168.1.40_usbshare2/Films/Films 3D/TRON Legacy (2010) [3D] [HSBS]/Sous l'Antarctique - Documentaire complet HD.mp4 et ainsi de suite .... –

+0

Finit j'ai oublié de changer 't' pour 'v'. Fixé. (vous avez probablement eu un 't' global défini comme cette chaîne) – jv110

0

J'émulé votre API à l'aide LFS et écrire le code qui fonctionne:

-- My block. Do not use in your project. ------ 
local lfs = require "lfs" 
local API = { } 

function API:FileSetDir(path) 
     return lfs.chdir (path) 
end 
function API:FileList() 
    local path= lfs.currentdir() 
    local t = {} 
    for entry in lfs.dir(path) do 
     t[#t+1] = entry 
    end 
    return t 
end 
--- End of my block ---------------------------------------------------- 
local finalpath={} 
local RootDir = 'd:/temp' 


function CheckDirectory(entry) 
     local CurDir = entry 
     local IsDir = API:FileSetDir(CurDir) -- return nil when error 
     local DirList = API:FileList() 
     print(CurDir) 
     if not IsDir then 
        print(CurDir .." - Not Directory") 
     else  
        for _,v in pairs(DirList) do 
           local tmp = CurDir.."/".. v 
           if true or string.find(v,"%.mkv$") or string.find(v,"%.mp4$") then -- true always for me 
             finalpath[#finalpath+1] = tmp 
             print(' >> '..tmp) 
           end 
           if not (v=='.' or v=='..') then        
            CheckDirectory(tmp) 
           end 
        end 
     end  
end 

CheckDirectory(RootDir) 
+0

Le système sur lequel je travaille ne supporte pas la bibliothèque Ifs. –

+1

@ Prakash.DTI Mais vous avez une API que je n'avais pas. Substituez vos fonctions. –

+0

Que voulez-vous dire par substitut? –