iostreams 0.20.1 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|