Resetting FileInputStream in Java so I can run multiple instances of another program in a test program
<p>My problem is that I was assigned to modify and improve upon a program that does LZW compression. My program, as far as I know, runs fine, but relies on System.in and System.out redirection for the input file and output file. For my test program, I run through a folder full of files and for each file, run 4 different tests on the program. To emulate the command line input/output redirection, on the first iteration of the loop for each file I do the following:</p>

<pre><code>FileOutputStream fos = new FileOutputStream(compressOut); // compressOut is compressed file
PrintStream ps = new PrintStream(fos);
System.setOut(ps);
FileInputStream fis = new FileInputStream(file); // file is file to be compressed
System.setIn(fis);
fis.mark(0);// mark not supported so this is actually left over from my test code -- wanted to show I tried to do this
</code></pre>

<p>The first time it runs the program I'm testing, it works brilliantly and returns a compression ratio and prepares to write it to the program output file.</p>

<p>However, upon the second program call (and, if I were to eliminate all of the extra calls, the second iteration of the for loop) it crashes and returns that the input stream is empty. I haven't gotten the chance yet to see if the output stream will do the same thing, but what I have attempted to do to reset the stream is as follows:</p>

<p>Before each call program call, I have the following blocks of code which I **thought would fix the problem, but to no avail:</p>

<pre><code>//System.setIn(null); // Tried - didn't work
//System.setOut(null); // Tried - didn't work
fos.close();
ps.close();
fis.close();
fos = new FileOutputStream(compressOut);
ps = new PrintStream(fos);
System.setOut(ps);
fis = new FileInputStream(file);
System.setIn(fis);
//fis.reset(); // Tried - didn't work
</code></pre>

<p>I've tried all sorts of combinations of different ways to reset the input stream, but every solution still returns the same result, an error message indicating that it's reading from an empty input stream - an error which means that the stream is at the end of the file (or there is nothing in the file).</p>

<p>The only other error I can get is that mark() isn't supported when I call reset if I attempt the mark(0); and reset(); methods.</p>

<p>I've done reading and can't find any solid answers as to how to get this to work. The program turns the <code>StdIn</code> into a <code>BufferedInputStream</code> and <code>StdOut</code> to a <code>BufferedOutputStream</code>, so I need a method that will be compatible and provide performance similar to StdIn/StdOut redirection.</p>

<p><strong>TL;DR</strong>: I need to reset my <code>FileInputStream</code> and can't do so using mark() reset() nor if I reinitialize the <code>FileInputStream</code></p>

<p><strong>Update:</strong> tried wrapping FIS into a <code>BufferedInputStream</code> as suggested on a similar post, where mark() is supported. However, the <code>mark()</code> and <code>reset()</code> methods are only good for the size of the <code>BufferedInputStream</code> (which I believe is 4096 bytes) which pretty much excludes the potential usefulness of the mark/reset feature in all of my files. They are all larger than 4kB :(</p>

<p><strong>Update 2:</strong> I have decided to post the full snippet of code from where I begin the for-loop to where the empty stream error occurs, in case anyone can see something I can't. This is the code in question:</p>

<pre><code>public static void main(String[] args) throws IOException, InterruptedException {
    File programOutputPath = new File("-- the compression file path --");
    File folderPath = new File("-- the relative folder path --");
    File compressOut = new File(folderPath + "compressed.lzw");
    File[] allFiles = folderPath.listFiles(); // get an array of all files
    FileWriter fw = new FileWriter(programOutputPath);
    for(File file : allFiles) {
        FileOutputStream fos = new FileOutputStream(compressOut);
        PrintStream ps = new PrintStream(fos);
        System.setOut(ps);
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        System.setIn(bis);
        String[] cArgs = new String[2];
        cArgs[0] = "-"; cArgs[1] = "-n";
        String[] dArgs = new String[1];
        dArgs[0] = "+";
        String[] LZWArgs = new String[1];
        LZWArgs[0] = "-";
        System.err.println("File: " + file.toString());
        if(!file.canWrite()) {
            System.err.println("SKIPPED FILE");
        }
        if(file.getName().equalsIgnoreCase(".gitignore") || file.getName().equalsIgnoreCase("compressed.lzw")) continue;
        MyLZW.main(cArgs); // runs fine
        if(decompress) {
            //MyLZW.main(dArgs); // not executing this
        }
        long sizeUnc = file.length();
        long sizeC = compressOut.length();
        double ratio = (double)sizeUnc/(double)sizeC; // compression ratio is correct
        System.err.println("java MyLZW - -r &lt;" + file.getName() + "&gt; " + " compressed.lzw compression ratio:" + ratio ); // works fine
        fw.write("java MyLZW - -n &lt;" + file.getName() + "&gt; " + " compressed.lzw compression ratio:" + ratio + "\n");
        cArgs[1] = "-r";
        bis.close(); // close BufferedInputStream
        bis = new BufferedInputStream(new FileInputStream(file)); // reinitialize BIS
        System.setIn(bis); // setIn to newly initialized BufferedInputStream
        MyLZW.main(cArgs); // crashes here b/c empty input stream
</code></pre>