Je sais comment récupérer le contenu d'un fichier zip normal avec RubyZip. Mais j'ai eu des difficultés à découvrir le contenu d'un dossier zippé et j'espère que l'un des gars de U peut m'aider.
Ceci est le code que j'utilise pour décompresser: p>
Zip::ZipFile::open(@file_location) do |zip|
zip.each do |entry|
next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file?
logger.debug "#{entry.name}"
@data = entry.get_input_stream.read
# How do i create a file from a stream?
end
end
3 Réponses :
Je pense que votre problème n'est pas si vous devez écrire un fichier d'un flux ou non. Fondamentalement, si vous appelez Lorsque vous dites p> Lorsque j'essaie ensuite de créer le fichier, il me dit que le fichier ne peut pas être trouvé p>
BlockQuote> Je pense que ce qui se passe est que le répertoire parent du fichier que vous souhaitez créer n'existe pas (dans votre cas le dossier de test fichier.new code> it Créez un nouveau io-Stream ( fichier code> est une sous-classe de io code>). Par conséquent, tout ce que vous voulez faire avec le flux du zipfile devrait également fonctionner avec un fichier régulier.
code>). Ce que vous voulez faire, c'est quelque chose comme ça (non testé): p>
J'ai essayé votre code, mais cela ne crée que le dossier parent de l'entrée à la racine de mon projet. Je ne peux toujours pas accéder à l'entrée. C'est en fait un errno :: Enoent - Je pensais que je devrais mentionner cela. thx tho
Je l'ai résolu en utilisant un flux et en créant un stringio. Voici le code
Zip::ZipFile::open(@file_location) do |zip|
zip.each do |entry|
next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file?
begin
# the normal unzip-code
rescue Errno::ENOENT
# when the entry can not be found
@data = entry.get_input_stream.read
@file = StringIO.new(@data)
@file.class.class_eval { attr_accessor :original_filename, :content_type }
@file.original_filename = entry.name
@file.content_type = MIME::Types.type_for(entry.name)
# save it / whatever
end
end
end
Cette première ligne devrait être: zip :: zipfile.open (@file_location) faire | zip | code>
J'ai trouvé qu'une approche plus simple basée sur Jhwist a fonctionné OK:
Zip::File.open(@file_location) do |zipfile|
zipfile.each do |entry|
# The 'next if...' code can go here, though I didn't use it
unless File.exist?(entry.name)
FileUtils::mkdir_p(File.dirname(entry.name))
zipfile.extract(entry, entry.name)
end
end
end
Cette approche ne préserve pas les autorisations des fichiers. Comment puis-je préserver les autorisations après avoir extraites?
C'est bizarre que zip.mkdir code> ne fonctionne pas comme mkdir_p code> si entrée.name code> inclut tout le chemin. Pour cette raison, nous devons utiliser fileautils code> (