001 /* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package com.google.common.io; 018 019 import com.google.common.annotations.Beta; 020 import com.google.common.annotations.VisibleForTesting; 021 022 import java.io.Closeable; 023 import java.io.IOException; 024 import java.util.logging.Level; 025 import java.util.logging.Logger; 026 027 import javax.annotation.Nullable; 028 029 /** 030 * Utility methods for working with {@link Closeable} objects. 031 * 032 * @author Michael Lancaster 033 * @since 1.0 034 */ 035 @Beta 036 public final class Closeables { 037 @VisibleForTesting static final Logger logger 038 = Logger.getLogger(Closeables.class.getName()); 039 040 private Closeables() {} 041 042 /** 043 * Closes a {@link Closeable}, with control over whether an 044 * {@code IOException} may be thrown. This is primarily useful in a 045 * finally block, where a thrown exception needs to be logged but not 046 * propagated (otherwise the original exception will be lost). 047 * 048 * <p>If {@code swallowIOException} is true then we never throw 049 * {@code IOException} but merely log it. 050 * 051 * <p>Example: 052 * 053 * <p><pre>public void useStreamNicely() throws IOException { 054 * SomeStream stream = new SomeStream("foo"); 055 * boolean threw = true; 056 * try { 057 * // Some code which does something with the Stream. May throw a 058 * // Throwable. 059 * threw = false; // No throwable thrown. 060 * } finally { 061 * // Close the stream. 062 * // If an exception occurs, only rethrow it if (threw==false). 063 * Closeables.close(stream, threw); 064 * } 065 * </pre> 066 * 067 * @param closeable the {@code Closeable} object to be closed, or null, 068 * in which case this method does nothing 069 * @param swallowIOException if true, don't propagate IO exceptions 070 * thrown by the {@code close} methods 071 * @throws IOException if {@code swallowIOException} is false and 072 * {@code close} throws an {@code IOException}. 073 */ 074 public static void close(@Nullable Closeable closeable, 075 boolean swallowIOException) throws IOException { 076 if (closeable == null) { 077 return; 078 } 079 try { 080 closeable.close(); 081 } catch (IOException e) { 082 if (swallowIOException) { 083 logger.log(Level.WARNING, 084 "IOException thrown while closing Closeable.", e); 085 } else { 086 throw e; 087 } 088 } 089 } 090 091 /** 092 * Equivalent to calling {@code close(closeable, true)}, but with no 093 * IOException in the signature. 094 * @param closeable the {@code Closeable} object to be closed, or null, in 095 * which case this method does nothing 096 */ 097 public static void closeQuietly(@Nullable Closeable closeable) { 098 try { 099 close(closeable, true); 100 } catch (IOException e) { 101 logger.log(Level.SEVERE, "IOException should not have been thrown.", e); 102 } 103 } 104 }