@@ -52,28 +52,49 @@ public ByteBuffer get(String[] keys, long start) {
5252 }
5353
5454 public String getArchiveComment () throws IOException {
55- ByteBuffer buffer = underlyingStore .read ();
56- if (buffer == null ) {
57- return null ;
58- }
59- byte [] bufArray ;
60- if (buffer .hasArray ()) {
61- bufArray = buffer .array ();
62- } else {
63- bufArray = new byte [buffer .remaining ()];
64- buffer .duplicate ().get (bufArray );
55+ // Attempt to read from the end of the file to find the EOCD record.
56+ // We try a small chunk first (1KB) which covers most short comments (or no comment),
57+ // then the maximum possible EOCD size (approx 65KB).
58+ int [] readSizes = {1024 , 65535 + 22 };
59+
60+ for (int size : readSizes ) {
61+ ByteBuffer buffer ;
62+ long fileSize = underlyingStore .getSize ();
63+
64+ if (fileSize < size ){
65+ buffer = underlyingStore .read ();
66+ }
67+ else {
68+ buffer = underlyingStore .read (fileSize - size );
69+ }
70+
71+ if (buffer == null ) {
72+ return null ;
73+ }
74+
75+ byte [] bufArray ;
76+ if (buffer .hasArray ()) {
77+ bufArray = buffer .array ();
78+ } else {
79+ bufArray = new byte [buffer .remaining ()];
80+ buffer .duplicate ().get (bufArray );
81+ }
82+
83+ String comment = getZipCommentFromBuffer (bufArray );
84+ if (comment != null ) {
85+ return comment ;
86+ }
6587 }
66- return getZipCommentFromBuffer ( bufArray ) ;
88+ return null ;
6789 }
68-
6990 @ Nullable
7091 @ Override
7192 public ByteBuffer get (String [] keys , long start , long end ) {
72- ByteBuffer buffer = underlyingStore .read ();
73- if (buffer == null ) {
93+ InputStream inputStream = underlyingStore .getInputStream ();
94+ if (inputStream == null ) {
7495 return null ;
7596 }
76- try (ZipArchiveInputStream zis = new ZipArchiveInputStream (new ByteBufferBackedInputStream ( buffer ) )) {
97+ try (ZipArchiveInputStream zis = new ZipArchiveInputStream (inputStream )) {
7798 ZipArchiveEntry entry ;
7899 while ((entry = zis .getNextEntry ()) != null ) {
79100 String entryName = entry .getName ();
@@ -147,11 +168,11 @@ public ReadOnlyZipStore(@Nonnull String underlyingStorePath) {
147168 public Stream <String []> list (String [] keys ) {
148169 Stream .Builder <String []> builder = Stream .builder ();
149170
150- ByteBuffer buffer = underlyingStore .read ();
151- if (buffer == null ) {
171+ InputStream inputStream = underlyingStore .getInputStream ();
172+ if (inputStream == null ) {
152173 return builder .build ();
153174 }
154- try (ZipArchiveInputStream zis = new ZipArchiveInputStream (new ByteBufferBackedInputStream ( buffer ) )) {
175+ try (ZipArchiveInputStream zis = new ZipArchiveInputStream (inputStream )) {
155176 ZipArchiveEntry entry ;
156177 String prefix = resolveKeys (keys );
157178 while ((entry = zis .getNextEntry ()) != null ) {
@@ -166,9 +187,7 @@ public Stream<String[]> list(String[] keys) {
166187 String [] entryKeys = resolveEntryKeys (entryName .substring (prefix .length ()));
167188 builder .add (entryKeys );
168189 }
169- } catch (IOException e ) {
170- return null ;
171- }
190+ } catch (IOException ignored ) {}
172191 return builder .build ();
173192 }
174193
@@ -201,8 +220,42 @@ public InputStream getInputStream(String[] keys, long start, long end) {
201220 return new BoundedInputStream (zis , bytesToRead );
202221 }
203222 return null ;
223+ } catch (IOException ignored ) {}
224+ return null ;
225+ }
226+
227+ @ Override
228+ public long getSize (String [] keys ) {
229+ InputStream inputStream = underlyingStore .getInputStream ();
230+ if (inputStream == null ) {
231+ throw new RuntimeException (new IOException ("Underlying store input stream is null" ));
232+ }
233+ try (ZipArchiveInputStream zis = new ZipArchiveInputStream (inputStream )) {
234+ ZipArchiveEntry entry ;
235+ while ((entry = zis .getNextEntry ()) != null ) {
236+ String entryName = entry .getName ();
237+
238+ if (entryName .startsWith ("/" )) {
239+ entryName = entryName .substring (1 );
240+ }
241+ if (entry .isDirectory () || !entryName .equals (resolveKeys (keys ))) {
242+ continue ;
243+ }
244+ long size = entry .getSize ();
245+ if (size < 0 ) {
246+ // read the entire entry to determine size
247+ size = 0 ;
248+ byte [] bufferArray = new byte [8192 ];
249+ int len ;
250+ while ((len = zis .read (bufferArray )) != -1 ) {
251+ size += len ;
252+ }
253+ }
254+ return size ;
255+ }
256+ throw new RuntimeException (new java .io .FileNotFoundException ("Key not found: " + resolveKeys (keys )));
204257 } catch (IOException e ) {
258+ throw new RuntimeException (e );
205259 }
206- return null ;
207260 }
208261}
0 commit comments