Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (C) 2007 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.io;
     18 
     19 import com.google.common.annotations.Beta;
     20 import com.google.common.annotations.VisibleForTesting;
     21 
     22 import java.io.Closeable;
     23 import java.io.IOException;
     24 import java.util.logging.Level;
     25 import java.util.logging.Logger;
     26 
     27 import javax.annotation.Nullable;
     28 
     29 /**
     30  * Utility methods for working with {@link Closeable} objects.
     31  *
     32  * @author Michael Lancaster
     33  * @since 1.0
     34  */
     35 @Beta
     36 public final class Closeables {
     37   @VisibleForTesting static final Logger logger
     38       = Logger.getLogger(Closeables.class.getName());
     39 
     40   private Closeables() {}
     41 
     42   /**
     43    * Closes a {@link Closeable}, with control over whether an
     44    * {@code IOException} may be thrown. This is primarily useful in a
     45    * finally block, where a thrown exception needs to be logged but not
     46    * propagated (otherwise the original exception will be lost).
     47    *
     48    * <p>If {@code swallowIOException} is true then we never throw
     49    * {@code IOException} but merely log it.
     50    *
     51    * <p>Example:
     52    *
     53    * <p><pre>public void useStreamNicely() throws IOException {
     54    * SomeStream stream = new SomeStream("foo");
     55    * boolean threw = true;
     56    * try {
     57    *   // Some code which does something with the Stream. May throw a
     58    *   // Throwable.
     59    *   threw = false; // No throwable thrown.
     60    * } finally {
     61    *   // Close the stream.
     62    *   // If an exception occurs, only rethrow it if (threw==false).
     63    *   Closeables.close(stream, threw);
     64    * }
     65    * </pre>
     66    *
     67    * @param closeable the {@code Closeable} object to be closed, or null,
     68    *     in which case this method does nothing
     69    * @param swallowIOException if true, don't propagate IO exceptions
     70    *     thrown by the {@code close} methods
     71    * @throws IOException if {@code swallowIOException} is false and
     72    *     {@code close} throws an {@code IOException}.
     73    */
     74   public static void close(@Nullable Closeable closeable,
     75       boolean swallowIOException) throws IOException {
     76     if (closeable == null) {
     77       return;
     78     }
     79     try {
     80       closeable.close();
     81     } catch (IOException e) {
     82       if (swallowIOException) {
     83         logger.log(Level.WARNING,
     84             "IOException thrown while closing Closeable.", e);
     85       } else {
     86         throw e;
     87       }
     88     }
     89   }
     90 
     91   /**
     92    * Equivalent to calling {@code close(closeable, true)}, but with no
     93    * IOException in the signature.
     94    * @param closeable the {@code Closeable} object to be closed, or null, in
     95    *      which case this method does nothing
     96    */
     97   public static void closeQuietly(@Nullable Closeable closeable) {
     98     try {
     99       close(closeable, true);
    100     } catch (IOException e) {
    101       logger.log(Level.SEVERE, "IOException should not have been thrown.", e);
    102     }
    103   }
    104 }
    105