iostreams 0.20.1 → 0.20.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/io_streams/version.rb +1 -1
- data/lib/io_streams/zip/reader.rb +40 -28
- data/test/files/multiple_files.zip +0 -0
- data/test/files/text.zip.gz +0 -0
- data/test/io_streams_test.rb +31 -0
- data/test/minimal_file_reader.rb +25 -0
- data/test/zip_reader_test.rb +30 -3
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f09dde2bcb517dd7c24e6bdf7bdfcfe313b2c5a17f3c8b1ac6caf850d1057364
|
4
|
+
data.tar.gz: 8886732d0a04007205ac6b0f76aede0efc4617dc5fae51f06d9d9a4f5420fdb9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 894766215e6e1e6d942e3afbc5a1c797dbf5abf7a885a0a63e9fb29985e77f9ff84449d53f147484b0edb041e6bd89094b2824e3144ba0020cbadb8dc9fb9943
|
7
|
+
data.tar.gz: 69806e7e4ff2cd9184c63a906ca25d44a69003c52e477fe96fa563bc99590f117b0701e0231cf8543e617cb31f63c0ed615a2d54ff8d757e00eb1e420d637d1d
|
data/lib/io_streams/version.rb
CHANGED
@@ -3,7 +3,12 @@ module IOStreams
|
|
3
3
|
class Reader
|
4
4
|
# Read from a zip file or stream, decompressing the contents as it is read
|
5
5
|
# The input stream from the first file found in the zip file is passed
|
6
|
-
# to the supplied block
|
6
|
+
# to the supplied block.
|
7
|
+
#
|
8
|
+
# Parameters:
|
9
|
+
# entry_file_name: [String]
|
10
|
+
# Name of the file within the Zip file to read.
|
11
|
+
# Default: Read the first file found in the zip file.
|
7
12
|
#
|
8
13
|
# Example:
|
9
14
|
# IOStreams::Zip::Reader.open('abc.zip') do |io_stream|
|
@@ -12,58 +17,65 @@ module IOStreams
|
|
12
17
|
# puts data
|
13
18
|
# end
|
14
19
|
# end
|
15
|
-
def self.open(file_name_or_io,
|
16
|
-
if !defined?(JRuby) && !defined?(::Zip)
|
17
|
-
# MRI needs Ruby Zip, since it only has native support for GZip
|
18
|
-
begin
|
19
|
-
require 'zip'
|
20
|
-
rescue LoadError => exc
|
21
|
-
raise(LoadError, "Install gem 'rubyzip' to read and write Zip files: #{exc.message}")
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
20
|
+
def self.open(file_name_or_io, entry_file_name: nil, &block)
|
25
21
|
# File name supplied
|
26
|
-
return read_file(file_name_or_io, &block) unless IOStreams.reader_stream?(file_name_or_io)
|
22
|
+
return read_file(file_name_or_io, entry_file_name, &block) unless IOStreams.reader_stream?(file_name_or_io)
|
27
23
|
|
28
|
-
# ZIP can only work against a file, not a stream, so create temp file.
|
24
|
+
# Ruby ZIP gem uses `#seek` so can only work against a file, not a stream, so create temp file.
|
25
|
+
# JRuby ZIP requires an InputStream.
|
29
26
|
IOStreams::File::Path.temp_file_name('iostreams_zip') do |temp_file_name|
|
30
27
|
IOStreams.copy(file_name_or_io, temp_file_name, target_options: {streams: []})
|
31
|
-
read_file(temp_file_name, &block)
|
28
|
+
read_file(temp_file_name, entry_file_name, &block)
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
35
32
|
if defined?(JRuby)
|
36
33
|
# Java has built-in support for Zip files
|
37
|
-
def self.read_file(file_name,
|
34
|
+
def self.read_file(file_name, entry_file_name)
|
38
35
|
fin = Java::JavaIo::FileInputStream.new(file_name)
|
39
36
|
zin = Java::JavaUtilZip::ZipInputStream.new(fin)
|
40
|
-
|
41
|
-
|
37
|
+
|
38
|
+
get_entry(zin, entry_file_name) ||
|
39
|
+
raise(Java::JavaUtilZip::ZipException.new("File #{entry_file_name} not found within zip file."))
|
40
|
+
|
41
|
+
yield(zin.to_io)
|
42
42
|
ensure
|
43
43
|
zin.close if zin
|
44
44
|
fin.close if fin
|
45
45
|
end
|
46
46
|
|
47
47
|
else
|
48
|
-
|
49
48
|
# Read from a zip file or stream, decompressing the contents as it is read
|
50
49
|
# The input stream from the first file found in the zip file is passed
|
51
50
|
# to the supplied block
|
52
|
-
def self.read_file(file_name,
|
53
|
-
|
54
|
-
|
55
|
-
zin.get_next_entry
|
56
|
-
block.call(zin)
|
57
|
-
ensure
|
51
|
+
def self.read_file(file_name, entry_file_name)
|
52
|
+
if !defined?(::Zip)
|
53
|
+
# MRI needs Ruby Zip, since it only has native support for GZip
|
58
54
|
begin
|
59
|
-
|
60
|
-
rescue
|
61
|
-
|
62
|
-
# does not have a #closed? method
|
55
|
+
require 'zip'
|
56
|
+
rescue LoadError => exc
|
57
|
+
raise(LoadError, "Install gem 'rubyzip' to read and write Zip files: #{exc.message}")
|
63
58
|
end
|
64
59
|
end
|
60
|
+
|
61
|
+
::Zip::InputStream.open(file_name) do |zin|
|
62
|
+
get_entry(zin, entry_file_name) ||
|
63
|
+
raise(::Zip::EntryNameError, "File #{entry_file_name} not found within zip file.")
|
64
|
+
yield(zin)
|
65
|
+
end
|
65
66
|
end
|
67
|
+
end
|
66
68
|
|
69
|
+
def self.get_entry(zin, entry_file_name)
|
70
|
+
if entry_file_name.nil?
|
71
|
+
zin.get_next_entry
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
while entry = zin.get_next_entry
|
76
|
+
return true if entry.name == entry_file_name
|
77
|
+
end
|
78
|
+
false
|
67
79
|
end
|
68
80
|
end
|
69
81
|
end
|
Binary file
|
Binary file
|
data/test/io_streams_test.rb
CHANGED
@@ -30,6 +30,22 @@ class IOStreamsTest < Minitest::Test
|
|
30
30
|
bad_data.gsub("\xE9".b, '').gsub("\x07", '')
|
31
31
|
end
|
32
32
|
|
33
|
+
let :multiple_zip_file_name do
|
34
|
+
File.join(File.dirname(__FILE__), 'files', 'multiple_files.zip')
|
35
|
+
end
|
36
|
+
|
37
|
+
let :zip_gz_file_name do
|
38
|
+
File.join(File.dirname(__FILE__), 'files', 'text.zip.gz')
|
39
|
+
end
|
40
|
+
|
41
|
+
let :contents_test_txt do
|
42
|
+
File.read(File.join(File.dirname(__FILE__), 'files', 'text.txt'))
|
43
|
+
end
|
44
|
+
|
45
|
+
let :contents_test_json do
|
46
|
+
File.read(File.join(File.dirname(__FILE__), 'files', 'test.json'))
|
47
|
+
end
|
48
|
+
|
33
49
|
after do
|
34
50
|
temp_file.delete
|
35
51
|
end
|
@@ -124,5 +140,20 @@ class IOStreamsTest < Minitest::Test
|
|
124
140
|
end
|
125
141
|
end
|
126
142
|
|
143
|
+
describe '.reader' do
|
144
|
+
it 'reads a zip file' do
|
145
|
+
result = IOStreams.reader(multiple_zip_file_name, streams: {zip: {entry_file_name: 'test.json'}}) do |io|
|
146
|
+
io.read
|
147
|
+
end
|
148
|
+
assert_equal contents_test_json, result
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'reads a zip file from within a gz file' do
|
152
|
+
result = IOStreams.reader(zip_gz_file_name) do |io|
|
153
|
+
io.read
|
154
|
+
end
|
155
|
+
assert_equal contents_test_txt, result
|
156
|
+
end
|
157
|
+
end
|
127
158
|
end
|
128
159
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# The miminum methods that any IOStreams Reader must implement.
|
2
|
+
class MinimalFileReader
|
3
|
+
def self.open(file_name)
|
4
|
+
io = new(file_name)
|
5
|
+
yield(io)
|
6
|
+
ensure
|
7
|
+
io.close if io
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(file_name)
|
11
|
+
@file = File.open(file_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def read(size = nil, outbuf = nil)
|
15
|
+
@file.read(size, outbuf)
|
16
|
+
end
|
17
|
+
|
18
|
+
def close
|
19
|
+
@file.close
|
20
|
+
end
|
21
|
+
|
22
|
+
def closed?
|
23
|
+
@file.closed
|
24
|
+
end
|
25
|
+
end
|
data/test/zip_reader_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
|
+
require_relative 'minimal_file_reader'
|
2
3
|
require 'zip'
|
3
4
|
|
4
5
|
class ZipReaderTest < Minitest::Test
|
@@ -7,20 +8,46 @@ class ZipReaderTest < Minitest::Test
|
|
7
8
|
File.join(File.dirname(__FILE__), 'files', 'text.zip')
|
8
9
|
end
|
9
10
|
|
11
|
+
let :multiple_zip_file_name do
|
12
|
+
File.join(File.dirname(__FILE__), 'files', 'multiple_files.zip')
|
13
|
+
end
|
14
|
+
|
15
|
+
let :contents_test_txt do
|
16
|
+
File.read(File.join(File.dirname(__FILE__), 'files', 'text.txt'))
|
17
|
+
end
|
18
|
+
|
19
|
+
let :contents_test_json do
|
20
|
+
File.read(File.join(File.dirname(__FILE__), 'files', 'test.json'))
|
21
|
+
end
|
22
|
+
|
10
23
|
let :decompressed do
|
11
24
|
Zip::File.open(file_name) { |zip_file| zip_file.first.get_input_stream.read }
|
12
25
|
end
|
13
26
|
|
14
27
|
describe '.open' do
|
15
|
-
it 'file' do
|
28
|
+
it 'reads the first file' do
|
16
29
|
result = IOStreams::Zip::Reader.open(file_name) do |io|
|
17
30
|
io.read
|
18
31
|
end
|
19
32
|
assert_equal decompressed, result
|
20
33
|
end
|
21
34
|
|
22
|
-
it '
|
23
|
-
result =
|
35
|
+
it 'reads entry within zip file' do
|
36
|
+
result = IOStreams::Zip::Reader.open(multiple_zip_file_name, entry_file_name: 'text.txt') do |io|
|
37
|
+
io.read
|
38
|
+
end
|
39
|
+
assert_equal contents_test_txt, result
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'reads another entry within zip file' do
|
43
|
+
result = IOStreams::Zip::Reader.open(multiple_zip_file_name, entry_file_name: 'test.json') do |io|
|
44
|
+
io.read
|
45
|
+
end
|
46
|
+
assert_equal contents_test_json, result
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'reads from a stream' do
|
50
|
+
result = MinimalFileReader.open(file_name) do |file|
|
24
51
|
IOStreams::Zip::Reader.open(file) do |io|
|
25
52
|
io.read
|
26
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iostreams
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.20.
|
4
|
+
version: 0.20.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reid Morrison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- test/file_reader_test.rb
|
90
90
|
- test/file_writer_test.rb
|
91
91
|
- test/files/embedded_lines_test.csv
|
92
|
+
- test/files/multiple_files.zip
|
92
93
|
- test/files/spreadsheet.xlsx
|
93
94
|
- test/files/test.csv
|
94
95
|
- test/files/test.json
|
@@ -97,6 +98,7 @@ files:
|
|
97
98
|
- test/files/text.txt.gz
|
98
99
|
- test/files/text.txt.gz.zip
|
99
100
|
- test/files/text.zip
|
101
|
+
- test/files/text.zip.gz
|
100
102
|
- test/files/unclosed_quote_test.csv
|
101
103
|
- test/gzip_reader_test.rb
|
102
104
|
- test/gzip_writer_test.rb
|
@@ -104,6 +106,7 @@ files:
|
|
104
106
|
- test/io_streams_test.rb
|
105
107
|
- test/line_reader_test.rb
|
106
108
|
- test/line_writer_test.rb
|
109
|
+
- test/minimal_file_reader.rb
|
107
110
|
- test/path_test.rb
|
108
111
|
- test/pgp_reader_test.rb
|
109
112
|
- test/pgp_test.rb
|
@@ -147,6 +150,7 @@ test_files:
|
|
147
150
|
- test/base_path_test.rb
|
148
151
|
- test/line_reader_test.rb
|
149
152
|
- test/xlsx_reader_test.rb
|
153
|
+
- test/minimal_file_reader.rb
|
150
154
|
- test/row_writer_test.rb
|
151
155
|
- test/zip_reader_test.rb
|
152
156
|
- test/bzip2_writer_test.rb
|
@@ -166,11 +170,13 @@ test_files:
|
|
166
170
|
- test/files/embedded_lines_test.csv
|
167
171
|
- test/files/test.csv
|
168
172
|
- test/files/test.json
|
173
|
+
- test/files/text.zip.gz
|
169
174
|
- test/files/unclosed_quote_test.csv
|
170
175
|
- test/files/text.txt.bz2
|
171
176
|
- test/files/text.txt.gz.zip
|
172
177
|
- test/files/text.txt.gz
|
173
178
|
- test/files/text.txt
|
179
|
+
- test/files/multiple_files.zip
|
174
180
|
- test/gzip_reader_test.rb
|
175
181
|
- test/encode_reader_test.rb
|
176
182
|
- test/test_helper.rb
|