11 Replies Latest reply on Oct 10, 2007 10:02 AM by 807592

    How to reopen FileInputStream?


      Is it possible to re-open a FileInputStream or somehow reset it to the beginning so that I can read from it again? I would like to be able to do this without knowing which file name that string represents. I have gotten the file descriptor and tried to create a new stream based on that, but I get a "bad file descriptor" exception. Does anyone know any other way to do this?

      Thank you.

        • 1. Re: How to reopen FileInputStream?
          Read the API docs for FileInputStream.getChannel().
          • 2. Re: How to reopen FileInputStream?
            I have already tried that and I cannot get it to work. If I try to reset the channel to position 0, I get an exception:

            java.io.IOException: Bad file descriptor
                 at sun.nio.ch.FileChannelImpl.position0(Native Method)
                 at sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:284)

            If I try to get the descriptor from the existing stream and create a new stream based on that, I still get the same exception.

            FileInputStream does not support the reset() method.

            The issue may be due to the fact that the file is changed on disk, which is why I have to re-read it. However, the interface that I need to conform to only passes in the FileInputStream and not the File or its name. So how can I re-read the file that is associated with that stream without knowing its path?

            Does anyone have any other suggestions?
            • 3. Re: How to reopen FileInputStream?
              If you only have an InputStream defined as a parameter, and you need to read it twice, then your design is wrong. There is no guarantee that an InputStream can be reset, as you have already found out. It looks to me like the code you are writing isn't consistent with the interface you are attempting to implement.
              • 4. Re: How to reopen FileInputStream?
                The design of the code assumed that the file represented by the stream was static over time so it would cache the contents of the file in its own implementation, which is a limitation of that implementation since it is not true for the scenario I am working with. Therefore, I need to provide my own implementation which would allow me to refresh the cache periodically and still work with other code written arround the interface presented by the original implementation. The problem is that the origial design did not account for the sort of situation I am dealing with.

                Since the stream can be constructed from a File, I was hoping there was some way to retrieve that File or its path from an existing stream to create a new one or to clone or reset the existing stream.

                • 5. Re: How to reopen FileInputStream?
                  With channels it is possible to re-read a FileInputStream.
                  Here is a sample testing class (ReRead.java) to demonstrate it
                  The way to use it is:
                  1- Create a little testting text file (for instance sometextfile.txt).
                  2- Execute the class from the console:
                  java ReRead sometextfile.txt
                  3- While the execution is waiting for keyboard input, modify sometextfile.txt.
                  4- Hit <Enter> and look at the console.
                  import java.io.*;
                  import java.nio.*;
                  import java.nio.channels.*;
                  public class ReRead {
                      public static void main(String[] args) throws Exception {
                          if (args.length != 1)
                              throw new Exception("\nUsage: java ReRead {text file name}");
                          String fileName = args[0];
                          FileInputStream fis = new FileInputStream(fileName); // The only FileInputStream used.
                          // First time the FileInputStream is read.
                          System.out.println("First read:");
                          readFile(fis); // First time.
                          System.out.print("Modify the '" + fileName + "' file and then hit <Enter> at the console.");
                          // Second time the same FileInputStream is read.
                          System.out.println("Second read:");
                      private static void readFile(FileInputStream fis) throws Exception {
                          FileChannel fc = fis.getChannel();
                          ByteBuffer bb = ByteBuffer.allocate(1024);
                          WritableByteChannel wbc = Channels.newChannel(System.out);
                          fc.position(0); // <-- IMPORTANT! this reset the channel position.
                          System.out.println("-----start file-----");
                          while (fc.read(bb) != -1) {
                          System.out.println("-----end file-----");
                  • 6. Re: How to reopen FileInputStream?
                    Thanks jfbriere. That is a good suggestion. Unfortunately, it did not solve my problem. The trouble is that the stream gets closed somewhere so even resetting the channel will not alow me to read from it. I get a java.nio.channels.ClosedChannelException. What I really need is a way to reopen a stream or channel.
                    • 7. Re: How to reopen FileInputStream?
                      I need to provide my own implementation which would allow me to refresh the cache periodically
                      In that case I don't think I would attempt to have the method try to do the refreshing, since it clearly wasn't designed to do that. Instead I would try to have some outside object call the method repeatedly with the current data (at regular intervals, or whenever the resource changes, or at somebody's request).
                      • 8. Re: How to reopen FileInputStream?
                        Yes, I understand what you are saying. However, the code that I am trying to work with is a provided by sun and it is used in third party code which I do not have control over. I can provide my own implementation of the interface defined by sun and then have the third party code use that implementation of the interface (it is possible to select the implementation through setting system properties) but I cannot add a wrapper around that object since the thrid party code will not use it.

                        I guess it is just not possible to fix the problem. It is very frustrating that you need to pass a File or path to the constructor of a FileInputStream but there is no accessor which will give you that information back at a later time.

                        • 9. Re: How to reopen FileInputStream?
                          is you question actual?
                          you can implement interface similar to javax.mail.internet.SharedInputStream and use it follow:

                          SharedInputStream root = new SharedFileInputStream(fileName);
                          InputStream is1 = root.newStream(0,-1);


                          InputStream is2 = root.newStream(0,-1);

                          if you encounter a difficulty with implementing SharedInputStream interface, i will post some working code here
                          • 10. Re: How to reopen FileInputStream?
                            Thank God for RandomAccessFile:
                            import java.io.File;
                            import java.io.IOException;
                            import java.io.InputStream;
                            import java.io.RandomAccessFile;
                            public class ResettableFileInputStream extends InputStream {
                                 RandomAccessFile raFile;
                                 long mark;
                                 public ResettableFileInputStream(File file) throws IOException {
                                      this.raFile = new RandomAccessFile(file, "r");
                                 public int read() throws IOException {
                                      return raFile.read();
                                 public synchronized void mark(int readlimit) {
                                      try {
                                           mark = raFile.getFilePointer();
                                      } catch (Exception e) {
                                           throw new RuntimeException(e);
                                 public boolean markSupported() {
                                      return true;
                                 public int read(byte[] b, int off, int len) throws IOException {
                                      // TODO Auto-generated method stub
                                      return raFile.read(b, off, len);
                                 public synchronized void reset() throws IOException {
                                 public int available() throws IOException {
                                      // TODO Auto-generated method stub
                                      return (int) (raFile.length() - raFile.getFilePointer());
                                 public void close() throws IOException {
                                      // TODO Auto-generated method stub
                                 public long skip(long n) throws IOException {
                                      // TODO Auto-generated method stub
                                      long s = raFile.getFilePointer() + n;
                                      if (raFile.getFilePointer() + n > raFile.length())
                                           n = raFile.length() - raFile.getFilePointer();
                                      raFile.seek(raFile.getFilePointer() + n);
                                      return n;
                            • 11. Re: How to reopen FileInputStream?
                              I am also facing the same issue. Not able to reset the FileInputStream. In the approach mentioned above (using RandomAccessFile), the same problem would occur right ? i.e If the input stream gets closed then you will get an exception, which is also the case while using FileIOChannel.

                              Is there any other way of reseting the inputstream ?