< prev index next >

src/java.base/share/classes/java/io/FileInputStream.java

Print this page
rev 52044 : 8192939: Remove Finalize methods from FileInputStream and FileOutputStream
   1 /*
   2  * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  62  * @since   1.0
  63  */
  64 public
  65 class FileInputStream extends InputStream
  66 {
  67     /* File Descriptor - handle to the open file */
  68     private final FileDescriptor fd;
  69 
  70     /**
  71      * The path of the referenced file
  72      * (null if the stream is created with a file descriptor)
  73      */
  74     private final String path;
  75 
  76     private volatile FileChannel channel;
  77 
  78     private final Object closeLock = new Object();
  79 
  80     private volatile boolean closed;
  81 
  82     private final Object altFinalizer;
  83 
  84     /**
  85      * Creates a <code>FileInputStream</code> by
  86      * opening a connection to an actual file,
  87      * the file named by the path name <code>name</code>
  88      * in the file system.  A new <code>FileDescriptor</code>
  89      * object is created to represent this file
  90      * connection.
  91      * <p>
  92      * First, if there is a security
  93      * manager, its <code>checkRead</code> method
  94      * is called with the <code>name</code> argument
  95      * as its argument.
  96      * <p>
  97      * If the named file does not exist, is a directory rather than a regular
  98      * file, or for some other reason cannot be opened for reading then a
  99      * <code>FileNotFoundException</code> is thrown.
 100      *
 101      * @param      name   the system-dependent file name.
 102      * @exception  FileNotFoundException  if the file does not exist,
 103      *                   is a directory rather than a regular file,


 138      *               <code>checkRead</code> method denies read access to the file.
 139      * @see        java.io.File#getPath()
 140      * @see        java.lang.SecurityManager#checkRead(java.lang.String)
 141      */
 142     public FileInputStream(File file) throws FileNotFoundException {
 143         String name = (file != null ? file.getPath() : null);
 144         SecurityManager security = System.getSecurityManager();
 145         if (security != null) {
 146             security.checkRead(name);
 147         }
 148         if (name == null) {
 149             throw new NullPointerException();
 150         }
 151         if (file.isInvalid()) {
 152             throw new FileNotFoundException("Invalid file path");
 153         }
 154         fd = new FileDescriptor();
 155         fd.attach(this);
 156         path = name;
 157         open(name);
 158         altFinalizer = getFinalizer(this);
 159         if (altFinalizer == null) {
 160             FileCleanable.register(fd);       // open set the fd, register the cleanup
 161         }
 162     }
 163 
 164     /**
 165      * Creates a <code>FileInputStream</code> by using the file descriptor
 166      * <code>fdObj</code>, which represents an existing connection to an
 167      * actual file in the file system.
 168      * <p>
 169      * If there is a security manager, its <code>checkRead</code> method is
 170      * called with the file descriptor <code>fdObj</code> as its argument to
 171      * see if it's ok to read the file descriptor. If read access is denied
 172      * to the file descriptor a <code>SecurityException</code> is thrown.
 173      * <p>
 174      * If <code>fdObj</code> is null then a <code>NullPointerException</code>
 175      * is thrown.
 176      * <p>
 177      * This constructor does not throw an exception if <code>fdObj</code>
 178      * is {@link java.io.FileDescriptor#valid() invalid}.
 179      * However, if the methods are invoked on the resulting stream to attempt
 180      * I/O on the stream, an <code>IOException</code> is thrown.
 181      *
 182      * @param      fdObj   the file descriptor to be opened for reading.
 183      * @throws     SecurityException      if a security manager exists and its
 184      *                 <code>checkRead</code> method denies read access to the
 185      *                 file descriptor.
 186      * @see        SecurityManager#checkRead(java.io.FileDescriptor)
 187      */
 188     public FileInputStream(FileDescriptor fdObj) {
 189         SecurityManager security = System.getSecurityManager();
 190         if (fdObj == null) {
 191             throw new NullPointerException();
 192         }
 193         if (security != null) {
 194             security.checkRead(fdObj);
 195         }
 196         fd = fdObj;
 197         path = null;
 198         altFinalizer = null;
 199 
 200         /*
 201          * FileDescriptor is being shared by streams.
 202          * Register this stream with FileDescriptor tracker.
 203          */
 204         fd.attach(this);
 205     }
 206 
 207     /**
 208      * Opens the specified file for reading.
 209      * @param name the name of the file
 210      */
 211     private native void open0(String name) throws FileNotFoundException;
 212 
 213     // wrap native call to allow instrumentation
 214     /**
 215      * Opens the specified file for reading.
 216      * @param name the name of the file
 217      */
 218     private void open(String name) throws FileNotFoundException {


 420                         false, false, this);
 421                     if (closed) {
 422                         try {
 423                             // possible race with close(), benign since
 424                             // FileChannel.close is final and idempotent
 425                             fc.close();
 426                         } catch (IOException ioe) {
 427                             throw new InternalError(ioe); // should not happen
 428                         }
 429                     }
 430                 }
 431             }
 432         }
 433         return fc;
 434     }
 435 
 436     private static native void initIDs();
 437 
 438     static {
 439         initIDs();
 440     }
 441 
 442     /**
 443      * Ensures that the {@link #close} method of this file input stream is
 444      * called when there are no more references to it.
 445      * The {@link #finalize} method does not call {@link #close} directly.
 446      *
 447      * @apiNote
 448      * To release resources used by this stream {@link #close} should be called
 449      * directly or by try-with-resources.
 450      *
 451      * @implSpec
 452      * If this FileInputStream has been subclassed and the {@link #close}
 453      * method has been overridden, the {@link #close} method will be
 454      * called when the FileInputStream is unreachable.
 455      * Otherwise, it is implementation specific how the resource cleanup described in
 456      * {@link #close} is performed.
 457      *
 458      * @deprecated The {@code finalize} method has been deprecated and will be removed.
 459      *     Subclasses that override {@code finalize} in order to perform cleanup
 460      *     should be modified to use alternative cleanup mechanisms and
 461      *     to remove the overriding {@code finalize} method.
 462      *     When overriding the {@code finalize} method, its implementation must explicitly
 463      *     ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
 464      *     See the specification for {@link Object#finalize()} for further
 465      *     information about migration options.
 466      *
 467      * @exception  IOException  if an I/O error occurs.
 468      * @see        java.io.FileInputStream#close()
 469      */
 470     @Deprecated(since="9", forRemoval = true)
 471     protected void finalize() throws IOException {
 472     }
 473 
 474     /*
 475      * Returns a finalizer object if the FIS needs a finalizer; otherwise null.
 476      * If the FIS has a close method; it needs an AltFinalizer.
 477      */
 478     private static Object getFinalizer(FileInputStream fis) {
 479         Class<?> clazz = fis.getClass();
 480         while (clazz != FileInputStream.class) {
 481             try {
 482                 clazz.getDeclaredMethod("close");
 483                 return new AltFinalizer(fis);
 484             } catch (NoSuchMethodException nsme) {
 485                 // ignore
 486             }
 487             clazz = clazz.getSuperclass();
 488         }
 489         return null;
 490     }
 491     /**
 492      * Class to call {@code FileInputStream.close} when finalized.
 493      * If finalization of the stream is needed, an instance is created
 494      * in its constructor(s).  When the set of instances
 495      * related to the stream is unreachable, the AltFinalizer performs
 496      * the needed call to the stream's {@code close} method.
 497      */
 498     static class AltFinalizer {
 499         private final FileInputStream fis;
 500 
 501         AltFinalizer(FileInputStream fis) {
 502             this.fis = fis;
 503         }
 504 
 505         @Override
 506         @SuppressWarnings("deprecation")
 507         protected final void finalize() {
 508             try {
 509                 if ((fis.fd != null) && (fis.fd != FileDescriptor.in)) {
 510                     /* if fd is shared, the references in FileDescriptor
 511                      * will ensure that finalizer is only called when
 512                      * safe to do so. All references using the fd have
 513                      * become unreachable. We can call close()
 514                      */
 515                     fis.close();
 516                 }
 517             } catch (IOException ioe) {
 518                 // ignore
 519             }
 520         }
 521     }
 522 }
   1 /*
   2  * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  62  * @since   1.0
  63  */
  64 public
  65 class FileInputStream extends InputStream
  66 {
  67     /* File Descriptor - handle to the open file */
  68     private final FileDescriptor fd;
  69 
  70     /**
  71      * The path of the referenced file
  72      * (null if the stream is created with a file descriptor)
  73      */
  74     private final String path;
  75 
  76     private volatile FileChannel channel;
  77 
  78     private final Object closeLock = new Object();
  79 
  80     private volatile boolean closed;
  81 


  82     /**
  83      * Creates a <code>FileInputStream</code> by
  84      * opening a connection to an actual file,
  85      * the file named by the path name <code>name</code>
  86      * in the file system.  A new <code>FileDescriptor</code>
  87      * object is created to represent this file
  88      * connection.
  89      * <p>
  90      * First, if there is a security
  91      * manager, its <code>checkRead</code> method
  92      * is called with the <code>name</code> argument
  93      * as its argument.
  94      * <p>
  95      * If the named file does not exist, is a directory rather than a regular
  96      * file, or for some other reason cannot be opened for reading then a
  97      * <code>FileNotFoundException</code> is thrown.
  98      *
  99      * @param      name   the system-dependent file name.
 100      * @exception  FileNotFoundException  if the file does not exist,
 101      *                   is a directory rather than a regular file,


 136      *               <code>checkRead</code> method denies read access to the file.
 137      * @see        java.io.File#getPath()
 138      * @see        java.lang.SecurityManager#checkRead(java.lang.String)
 139      */
 140     public FileInputStream(File file) throws FileNotFoundException {
 141         String name = (file != null ? file.getPath() : null);
 142         SecurityManager security = System.getSecurityManager();
 143         if (security != null) {
 144             security.checkRead(name);
 145         }
 146         if (name == null) {
 147             throw new NullPointerException();
 148         }
 149         if (file.isInvalid()) {
 150             throw new FileNotFoundException("Invalid file path");
 151         }
 152         fd = new FileDescriptor();
 153         fd.attach(this);
 154         path = name;
 155         open(name);


 156         FileCleanable.register(fd);       // open set the fd, register the cleanup
 157     }

 158 
 159     /**
 160      * Creates a <code>FileInputStream</code> by using the file descriptor
 161      * <code>fdObj</code>, which represents an existing connection to an
 162      * actual file in the file system.
 163      * <p>
 164      * If there is a security manager, its <code>checkRead</code> method is
 165      * called with the file descriptor <code>fdObj</code> as its argument to
 166      * see if it's ok to read the file descriptor. If read access is denied
 167      * to the file descriptor a <code>SecurityException</code> is thrown.
 168      * <p>
 169      * If <code>fdObj</code> is null then a <code>NullPointerException</code>
 170      * is thrown.
 171      * <p>
 172      * This constructor does not throw an exception if <code>fdObj</code>
 173      * is {@link java.io.FileDescriptor#valid() invalid}.
 174      * However, if the methods are invoked on the resulting stream to attempt
 175      * I/O on the stream, an <code>IOException</code> is thrown.
 176      *
 177      * @param      fdObj   the file descriptor to be opened for reading.
 178      * @throws     SecurityException      if a security manager exists and its
 179      *                 <code>checkRead</code> method denies read access to the
 180      *                 file descriptor.
 181      * @see        SecurityManager#checkRead(java.io.FileDescriptor)
 182      */
 183     public FileInputStream(FileDescriptor fdObj) {
 184         SecurityManager security = System.getSecurityManager();
 185         if (fdObj == null) {
 186             throw new NullPointerException();
 187         }
 188         if (security != null) {
 189             security.checkRead(fdObj);
 190         }
 191         fd = fdObj;
 192         path = null;

 193 
 194         /*
 195          * FileDescriptor is being shared by streams.
 196          * Register this stream with FileDescriptor tracker.
 197          */
 198         fd.attach(this);
 199     }
 200 
 201     /**
 202      * Opens the specified file for reading.
 203      * @param name the name of the file
 204      */
 205     private native void open0(String name) throws FileNotFoundException;
 206 
 207     // wrap native call to allow instrumentation
 208     /**
 209      * Opens the specified file for reading.
 210      * @param name the name of the file
 211      */
 212     private void open(String name) throws FileNotFoundException {


 414                         false, false, this);
 415                     if (closed) {
 416                         try {
 417                             // possible race with close(), benign since
 418                             // FileChannel.close is final and idempotent
 419                             fc.close();
 420                         } catch (IOException ioe) {
 421                             throw new InternalError(ioe); // should not happen
 422                         }
 423                     }
 424                 }
 425             }
 426         }
 427         return fc;
 428     }
 429 
 430     private static native void initIDs();
 431 
 432     static {
 433         initIDs();

















































































 434     }
 435 }
< prev index next >