Returns the size of this source in bytes, even if doing so requires opening and traversing an entire stream. To avoid a potentially expensive operation, see {@link #sizeIfKnown}. <p>The default implementation calls {@link #sizeIfKnown} and returns the value if present. If absent, it will fall back
()
| 202 | * @throws IOException if an I/O error occurs while reading the size of this source |
| 203 | */ |
| 204 | public long size() throws IOException { |
| 205 | Optional<Long> sizeIfKnown = sizeIfKnown(); |
| 206 | if (sizeIfKnown.isPresent()) { |
| 207 | return sizeIfKnown.get(); |
| 208 | } |
| 209 | |
| 210 | Closer closer = Closer.create(); |
| 211 | try { |
| 212 | InputStream in = closer.register(openStream()); |
| 213 | return countBySkipping(in); |
| 214 | } catch (IOException e) { |
| 215 | // skip may not be supported... at any rate, try reading |
| 216 | } finally { |
| 217 | closer.close(); |
| 218 | } |
| 219 | |
| 220 | closer = Closer.create(); |
| 221 | try { |
| 222 | InputStream in = closer.register(openStream()); |
| 223 | return ByteStreams.exhaust(in); |
| 224 | } catch (Throwable e) { |
| 225 | throw closer.rethrow(e); |
| 226 | } finally { |
| 227 | closer.close(); |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | /** Counts the bytes in the given input stream using skip if possible. */ |
| 232 | private static long countBySkipping(InputStream in) throws IOException { |