You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2021/05/14 00:37:53 UTC

svn commit: r1889871 [16/17] - in /poi: site/src/documentation/content/xdocs/ site/src/documentation/content/xdocs/components/ trunk/ trunk/maven/ trunk/osgi/ trunk/osgi/src/test/java/org/apache/poi/osgi/ trunk/poi-examples/src/main/java/org/apache/poi...

Modified: poi/trunk/poi/src/test/java/org/apache/poi/poifs/filesystem/TestPOIFSStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/poifs/filesystem/TestPOIFSStream.java?rev=1889871&r1=1889870&r2=1889871&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/poifs/filesystem/TestPOIFSStream.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/poifs/filesystem/TestPOIFSStream.java Fri May 14 00:37:50 2021
@@ -17,6 +17,7 @@
 
 package org.apache.poi.poifs.filesystem;
 
+import static org.apache.poi.POIDataSamples.writeOutAndReadBack;
 import static org.hamcrest.CoreMatchers.hasItem;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsEqual.equalTo;
@@ -26,21 +27,28 @@ import static org.junit.jupiter.api.Asse
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.function.Function;
 
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.hpsf.DocumentSummaryInformation;
+import org.apache.poi.hpsf.NoPropertySetStreamException;
 import org.apache.poi.hpsf.PropertySet;
 import org.apache.poi.hpsf.PropertySetFactory;
 import org.apache.poi.hpsf.SummaryInformation;
@@ -55,6 +63,9 @@ import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.TempFile;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Tests {@link POIFSStream}
@@ -67,26 +78,25 @@ final class TestPOIFSStream {
      */
     @Test
     void testReadTinyStream() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"))) {
 
-        // 98 is actually the last block in a two block stream...
-        POIFSStream stream = new POIFSStream(fs, 98);
-        Iterator<ByteBuffer> i = stream.getBlockIterator();
-        assertTrue(i.hasNext());
-        ByteBuffer b = i.next();
-        assertFalse(i.hasNext());
-
-        // Check the contents
-        assertEquals((byte) 0x81, b.get());
-        assertEquals((byte) 0x00, b.get());
-        assertEquals((byte) 0x00, b.get());
-        assertEquals((byte) 0x00, b.get());
-        assertEquals((byte) 0x82, b.get());
-        assertEquals((byte) 0x00, b.get());
-        assertEquals((byte) 0x00, b.get());
-        assertEquals((byte) 0x00, b.get());
+            // 98 is actually the last block in a two block stream...
+            POIFSStream stream = new POIFSStream(fs, 98);
+            Iterator<ByteBuffer> i = stream.getBlockIterator();
+            assertTrue(i.hasNext());
+            ByteBuffer b = i.next();
+            assertFalse(i.hasNext());
 
-        fs.close();
+            // Check the contents
+            assertEquals((byte) 0x81, b.get());
+            assertEquals((byte) 0x00, b.get());
+            assertEquals((byte) 0x00, b.get());
+            assertEquals((byte) 0x00, b.get());
+            assertEquals((byte) 0x82, b.get());
+            assertEquals((byte) 0x00, b.get());
+            assertEquals((byte) 0x00, b.get());
+            assertEquals((byte) 0x00, b.get());
+        }
     }
 
     /**
@@ -94,38 +104,37 @@ final class TestPOIFSStream {
      */
     @Test
     void testReadShortStream() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
-
-        // 97 -> 98 -> end
-        POIFSStream stream = new POIFSStream(fs, 97);
-        Iterator<ByteBuffer> i = stream.getBlockIterator();
-        assertTrue(i.hasNext());
-        ByteBuffer b97 = i.next();
-        assertTrue(i.hasNext());
-        ByteBuffer b98 = i.next();
-        assertFalse(i.hasNext());
-
-        // Check the contents of the 1st block
-        assertEquals((byte) 0x01, b97.get());
-        assertEquals((byte) 0x00, b97.get());
-        assertEquals((byte) 0x00, b97.get());
-        assertEquals((byte) 0x00, b97.get());
-        assertEquals((byte) 0x02, b97.get());
-        assertEquals((byte) 0x00, b97.get());
-        assertEquals((byte) 0x00, b97.get());
-        assertEquals((byte) 0x00, b97.get());
-
-        // Check the contents of the 2nd block
-        assertEquals((byte) 0x81, b98.get());
-        assertEquals((byte) 0x00, b98.get());
-        assertEquals((byte) 0x00, b98.get());
-        assertEquals((byte) 0x00, b98.get());
-        assertEquals((byte) 0x82, b98.get());
-        assertEquals((byte) 0x00, b98.get());
-        assertEquals((byte) 0x00, b98.get());
-        assertEquals((byte) 0x00, b98.get());
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"))) {
 
-        fs.close();
+            // 97 -> 98 -> end
+            POIFSStream stream = new POIFSStream(fs, 97);
+            Iterator<ByteBuffer> i = stream.getBlockIterator();
+            assertTrue(i.hasNext());
+            ByteBuffer b97 = i.next();
+            assertTrue(i.hasNext());
+            ByteBuffer b98 = i.next();
+            assertFalse(i.hasNext());
+
+            // Check the contents of the 1st block
+            assertEquals((byte) 0x01, b97.get());
+            assertEquals((byte) 0x00, b97.get());
+            assertEquals((byte) 0x00, b97.get());
+            assertEquals((byte) 0x00, b97.get());
+            assertEquals((byte) 0x02, b97.get());
+            assertEquals((byte) 0x00, b97.get());
+            assertEquals((byte) 0x00, b97.get());
+            assertEquals((byte) 0x00, b97.get());
+
+            // Check the contents of the 2nd block
+            assertEquals((byte) 0x81, b98.get());
+            assertEquals((byte) 0x00, b98.get());
+            assertEquals((byte) 0x00, b98.get());
+            assertEquals((byte) 0x00, b98.get());
+            assertEquals((byte) 0x82, b98.get());
+            assertEquals((byte) 0x00, b98.get());
+            assertEquals((byte) 0x00, b98.get());
+            assertEquals((byte) 0x00, b98.get());
+        }
     }
 
     /**
@@ -133,59 +142,58 @@ final class TestPOIFSStream {
      */
     @Test
     void testReadLongerStream() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"))) {
 
-        ByteBuffer b0 = null;
-        ByteBuffer b1 = null;
-        ByteBuffer b22 = null;
-
-        // The stream at 0 has 23 blocks in it
-        POIFSStream stream = new POIFSStream(fs, 0);
-        Iterator<ByteBuffer> i = stream.getBlockIterator();
-        int count = 0;
-        while (i.hasNext()) {
-            ByteBuffer b = i.next();
-            if (count == 0) {
-                b0 = b;
-            }
-            if (count == 1) {
-                b1 = b;
-            }
-            if (count == 22) {
-                b22 = b;
+            ByteBuffer b0 = null;
+            ByteBuffer b1 = null;
+            ByteBuffer b22 = null;
+
+            // The stream at 0 has 23 blocks in it
+            POIFSStream stream = new POIFSStream(fs, 0);
+            Iterator<ByteBuffer> i = stream.getBlockIterator();
+            int count = 0;
+            while (i.hasNext()) {
+                ByteBuffer b = i.next();
+                if (count == 0) {
+                    b0 = b;
+                }
+                if (count == 1) {
+                    b1 = b;
+                }
+                if (count == 22) {
+                    b22 = b;
+                }
+
+                count++;
             }
+            assertEquals(23, count);
 
-            count++;
+            // Check the contents
+            //  1st block is at 0
+            assertNotNull(b0);
+            assertEquals((byte) 0x9e, b0.get());
+            assertEquals((byte) 0x75, b0.get());
+            assertEquals((byte) 0x97, b0.get());
+            assertEquals((byte) 0xf6, b0.get());
+
+            //  2nd block is at 1
+            assertNotNull(b1);
+            assertEquals((byte) 0x86, b1.get());
+            assertEquals((byte) 0x09, b1.get());
+            assertEquals((byte) 0x22, b1.get());
+            assertEquals((byte) 0xfb, b1.get());
+
+            //  last block is at 89
+            assertNotNull(b22);
+            assertEquals((byte) 0xfe, b22.get());
+            assertEquals((byte) 0xff, b22.get());
+            assertEquals((byte) 0x00, b22.get());
+            assertEquals((byte) 0x00, b22.get());
+            assertEquals((byte) 0x05, b22.get());
+            assertEquals((byte) 0x01, b22.get());
+            assertEquals((byte) 0x02, b22.get());
+            assertEquals((byte) 0x00, b22.get());
         }
-        assertEquals(23, count);
-
-        // Check the contents
-        //  1st block is at 0
-        assertNotNull(b0);
-        assertEquals((byte) 0x9e, b0.get());
-        assertEquals((byte) 0x75, b0.get());
-        assertEquals((byte) 0x97, b0.get());
-        assertEquals((byte) 0xf6, b0.get());
-
-        //  2nd block is at 1
-        assertNotNull(b1);
-        assertEquals((byte) 0x86, b1.get());
-        assertEquals((byte) 0x09, b1.get());
-        assertEquals((byte) 0x22, b1.get());
-        assertEquals((byte) 0xfb, b1.get());
-
-        //  last block is at 89
-        assertNotNull(b22);
-        assertEquals((byte) 0xfe, b22.get());
-        assertEquals((byte) 0xff, b22.get());
-        assertEquals((byte) 0x00, b22.get());
-        assertEquals((byte) 0x00, b22.get());
-        assertEquals((byte) 0x05, b22.get());
-        assertEquals((byte) 0x01, b22.get());
-        assertEquals((byte) 0x02, b22.get());
-        assertEquals((byte) 0x00, b22.get());
-
-        fs.close();
     }
 
     /**
@@ -193,50 +201,48 @@ final class TestPOIFSStream {
      */
     @Test
     void testReadStream4096() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
-
-        // 0 -> 1 -> 2 -> end
-        POIFSStream stream = new POIFSStream(fs, 0);
-        Iterator<ByteBuffer> i = stream.getBlockIterator();
-        assertTrue(i.hasNext());
-        ByteBuffer b0 = i.next();
-        assertTrue(i.hasNext());
-        ByteBuffer b1 = i.next();
-        assertTrue(i.hasNext());
-        ByteBuffer b2 = i.next();
-        assertFalse(i.hasNext());
-
-        // Check the contents of the 1st block
-        assertEquals((byte) 0x9E, b0.get());
-        assertEquals((byte) 0x75, b0.get());
-        assertEquals((byte) 0x97, b0.get());
-        assertEquals((byte) 0xF6, b0.get());
-        assertEquals((byte) 0xFF, b0.get());
-        assertEquals((byte) 0x21, b0.get());
-        assertEquals((byte) 0xD2, b0.get());
-        assertEquals((byte) 0x11, b0.get());
-
-        // Check the contents of the 2nd block
-        assertEquals((byte) 0x00, b1.get());
-        assertEquals((byte) 0x00, b1.get());
-        assertEquals((byte) 0x03, b1.get());
-        assertEquals((byte) 0x00, b1.get());
-        assertEquals((byte) 0x00, b1.get());
-        assertEquals((byte) 0x00, b1.get());
-        assertEquals((byte) 0x00, b1.get());
-        assertEquals((byte) 0x00, b1.get());
-
-        // Check the contents of the 3rd block
-        assertEquals((byte) 0x6D, b2.get());
-        assertEquals((byte) 0x00, b2.get());
-        assertEquals((byte) 0x00, b2.get());
-        assertEquals((byte) 0x00, b2.get());
-        assertEquals((byte) 0x03, b2.get());
-        assertEquals((byte) 0x00, b2.get());
-        assertEquals((byte) 0x46, b2.get());
-        assertEquals((byte) 0x00, b2.get());
-
-        fs.close();
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize4096.zvi"))) {
+            // 0 -> 1 -> 2 -> end
+            POIFSStream stream = new POIFSStream(fs, 0);
+            Iterator<ByteBuffer> i = stream.getBlockIterator();
+            assertTrue(i.hasNext());
+            ByteBuffer b0 = i.next();
+            assertTrue(i.hasNext());
+            ByteBuffer b1 = i.next();
+            assertTrue(i.hasNext());
+            ByteBuffer b2 = i.next();
+            assertFalse(i.hasNext());
+
+            // Check the contents of the 1st block
+            assertEquals((byte) 0x9E, b0.get());
+            assertEquals((byte) 0x75, b0.get());
+            assertEquals((byte) 0x97, b0.get());
+            assertEquals((byte) 0xF6, b0.get());
+            assertEquals((byte) 0xFF, b0.get());
+            assertEquals((byte) 0x21, b0.get());
+            assertEquals((byte) 0xD2, b0.get());
+            assertEquals((byte) 0x11, b0.get());
+
+            // Check the contents of the 2nd block
+            assertEquals((byte) 0x00, b1.get());
+            assertEquals((byte) 0x00, b1.get());
+            assertEquals((byte) 0x03, b1.get());
+            assertEquals((byte) 0x00, b1.get());
+            assertEquals((byte) 0x00, b1.get());
+            assertEquals((byte) 0x00, b1.get());
+            assertEquals((byte) 0x00, b1.get());
+            assertEquals((byte) 0x00, b1.get());
+
+            // Check the contents of the 3rd block
+            assertEquals((byte) 0x6D, b2.get());
+            assertEquals((byte) 0x00, b2.get());
+            assertEquals((byte) 0x00, b2.get());
+            assertEquals((byte) 0x00, b2.get());
+            assertEquals((byte) 0x03, b2.get());
+            assertEquals((byte) 0x00, b2.get());
+            assertEquals((byte) 0x46, b2.get());
+            assertEquals((byte) 0x00, b2.get());
+        }
     }
 
     /**
@@ -244,35 +250,33 @@ final class TestPOIFSStream {
      */
     @Test
     void testReadFailsOnLoop() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
-
-        // Hack the FAT so that it goes 0->1->2->0
-        fs.setNextBlock(0, 1);
-        fs.setNextBlock(1, 2);
-        fs.setNextBlock(2, 0);
-
-        // Now try to read
-        POIFSStream stream = new POIFSStream(fs, 0);
-        Iterator<ByteBuffer> i = stream.getBlockIterator();
-        assertTrue(i.hasNext());
-
-        // 1st read works
-        i.next();
-        assertTrue(i.hasNext());
-
-        // 2nd read works
-        i.next();
-        assertTrue(i.hasNext());
-
-        // 3rd read works
-        i.next();
-        assertTrue(i.hasNext());
-
-        // 4th read blows up as it loops back to 0
-        assertThrows(RuntimeException.class, i::next, "Loop should have been detected but wasn't!");
-        assertTrue(i.hasNext());
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"))) {
+            // Hack the FAT so that it goes 0->1->2->0
+            fs.setNextBlock(0, 1);
+            fs.setNextBlock(1, 2);
+            fs.setNextBlock(2, 0);
 
-        fs.close();
+            // Now try to read
+            POIFSStream stream = new POIFSStream(fs, 0);
+            Iterator<ByteBuffer> i = stream.getBlockIterator();
+            assertTrue(i.hasNext());
+
+            // 1st read works
+            i.next();
+            assertTrue(i.hasNext());
+
+            // 2nd read works
+            i.next();
+            assertTrue(i.hasNext());
+
+            // 3rd read works
+            i.next();
+            assertTrue(i.hasNext());
+
+            // 4th read blows up as it loops back to 0
+            assertThrows(RuntimeException.class, i::next, "Loop should have been detected but wasn't!");
+            assertTrue(i.hasNext());
+        }
     }
 
     /**
@@ -281,51 +285,50 @@ final class TestPOIFSStream {
      */
     @Test
     void testReadMiniStreams() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
-        POIFSMiniStore ministore = fs.getMiniStore();
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"))) {
+            POIFSMiniStore ministore = fs.getMiniStore();
 
-        // 178 -> 179 -> 180 -> end
-        POIFSStream stream = new POIFSStream(ministore, 178);
-        Iterator<ByteBuffer> i = stream.getBlockIterator();
-        assertTrue(i.hasNext());
-        ByteBuffer b178 = i.next();
-        assertTrue(i.hasNext());
-        ByteBuffer b179 = i.next();
-        assertTrue(i.hasNext());
-        ByteBuffer b180 = i.next();
-        assertFalse(i.hasNext());
-
-        // Check the contents of the 1st block
-        assertEquals((byte) 0xfe, b178.get());
-        assertEquals((byte) 0xff, b178.get());
-        assertEquals((byte) 0x00, b178.get());
-        assertEquals((byte) 0x00, b178.get());
-        assertEquals((byte) 0x05, b178.get());
-        assertEquals((byte) 0x01, b178.get());
-        assertEquals((byte) 0x02, b178.get());
-        assertEquals((byte) 0x00, b178.get());
-
-        // And the 2nd
-        assertEquals((byte) 0x6c, b179.get());
-        assertEquals((byte) 0x00, b179.get());
-        assertEquals((byte) 0x00, b179.get());
-        assertEquals((byte) 0x00, b179.get());
-        assertEquals((byte) 0x28, b179.get());
-        assertEquals((byte) 0x00, b179.get());
-        assertEquals((byte) 0x00, b179.get());
-        assertEquals((byte) 0x00, b179.get());
-
-        // And the 3rd
-        assertEquals((byte) 0x30, b180.get());
-        assertEquals((byte) 0x00, b180.get());
-        assertEquals((byte) 0x00, b180.get());
-        assertEquals((byte) 0x00, b180.get());
-        assertEquals((byte) 0x00, b180.get());
-        assertEquals((byte) 0x00, b180.get());
-        assertEquals((byte) 0x00, b180.get());
-        assertEquals((byte) 0x80, b180.get());
+            // 178 -> 179 -> 180 -> end
+            POIFSStream stream = new POIFSStream(ministore, 178);
+            Iterator<ByteBuffer> i = stream.getBlockIterator();
+            assertTrue(i.hasNext());
+            ByteBuffer b178 = i.next();
+            assertTrue(i.hasNext());
+            ByteBuffer b179 = i.next();
+            assertTrue(i.hasNext());
+            ByteBuffer b180 = i.next();
+            assertFalse(i.hasNext());
+
+            // Check the contents of the 1st block
+            assertEquals((byte) 0xfe, b178.get());
+            assertEquals((byte) 0xff, b178.get());
+            assertEquals((byte) 0x00, b178.get());
+            assertEquals((byte) 0x00, b178.get());
+            assertEquals((byte) 0x05, b178.get());
+            assertEquals((byte) 0x01, b178.get());
+            assertEquals((byte) 0x02, b178.get());
+            assertEquals((byte) 0x00, b178.get());
 
-        fs.close();
+            // And the 2nd
+            assertEquals((byte) 0x6c, b179.get());
+            assertEquals((byte) 0x00, b179.get());
+            assertEquals((byte) 0x00, b179.get());
+            assertEquals((byte) 0x00, b179.get());
+            assertEquals((byte) 0x28, b179.get());
+            assertEquals((byte) 0x00, b179.get());
+            assertEquals((byte) 0x00, b179.get());
+            assertEquals((byte) 0x00, b179.get());
+
+            // And the 3rd
+            assertEquals((byte) 0x30, b180.get());
+            assertEquals((byte) 0x00, b180.get());
+            assertEquals((byte) 0x00, b180.get());
+            assertEquals((byte) 0x00, b180.get());
+            assertEquals((byte) 0x00, b180.get());
+            assertEquals((byte) 0x00, b180.get());
+            assertEquals((byte) 0x00, b180.get());
+            assertEquals((byte) 0x80, b180.get());
+        }
     }
 
     /**
@@ -333,32 +336,31 @@ final class TestPOIFSStream {
      */
     @Test
     void testReplaceStream() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"))) {
 
-        byte[] data = new byte[512];
-        for (int i = 0; i < data.length; i++) {
-            data[i] = (byte) (i % 256);
-        }
+            byte[] data = new byte[512];
+            for (int i = 0; i < data.length; i++) {
+                data[i] = (byte) (i % 256);
+            }
 
-        // 98 is actually the last block in a two block stream...
-        POIFSStream stream = new POIFSStream(fs, 98);
-        stream.updateContents(data);
+            // 98 is actually the last block in a two block stream...
+            POIFSStream stream = new POIFSStream(fs, 98);
+            stream.updateContents(data);
 
-        // Check the reading of blocks
-        Iterator<ByteBuffer> it = stream.getBlockIterator();
-        assertTrue(it.hasNext());
-        ByteBuffer b = it.next();
-        assertFalse(it.hasNext());
+            // Check the reading of blocks
+            Iterator<ByteBuffer> it = stream.getBlockIterator();
+            assertTrue(it.hasNext());
+            ByteBuffer b = it.next();
+            assertFalse(it.hasNext());
 
-        // Now check the contents
-        data = new byte[512];
-        b.get(data);
-        for (int i = 0; i < data.length; i++) {
-            byte exp = (byte) (i % 256);
-            assertEquals(exp, data[i]);
+            // Now check the contents
+            data = new byte[512];
+            b.get(data);
+            for (int i = 0; i < data.length; i++) {
+                byte exp = (byte) (i % 256);
+                assertEquals(exp, data[i]);
+            }
         }
-
-        fs.close();
     }
 
     /**
@@ -455,92 +457,91 @@ final class TestPOIFSStream {
      */
     @Test
     void testWriteNewStream() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"))) {
 
-        // 100 is our first free one
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
-
-
-        // Add a single block one
-        byte[] data = new byte[512];
-        for (int i = 0; i < data.length; i++) {
-            data[i] = (byte) (i % 256);
-        }
-
-        POIFSStream stream = new POIFSStream(fs);
-        stream.updateContents(data);
-
-        // Check it was allocated properly
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
-        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
+            // 100 is our first free one
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
 
-        // And check the contents
-        Iterator<ByteBuffer> it = stream.getBlockIterator();
-        int count = 0;
-        while (it.hasNext()) {
-            ByteBuffer b = it.next();
-            data = new byte[512];
-            b.get(data);
+
+            // Add a single block one
+            byte[] data = new byte[512];
             for (int i = 0; i < data.length; i++) {
-                byte exp = (byte) (i % 256);
-                assertEquals(exp, data[i]);
+                data[i] = (byte) (i % 256);
             }
-            count++;
-        }
-        assertEquals(1, count);
 
+            POIFSStream stream = new POIFSStream(fs);
+            stream.updateContents(data);
+
+            // Check it was allocated properly
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+            assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
 
-        // And a multi block one
-        data = new byte[512 * 3];
-        for (int i = 0; i < data.length; i++) {
-            data[i] = (byte) (i % 256);
-        }
-
-        stream = new POIFSStream(fs);
-        stream.updateContents(data);
-
-        // Check it was allocated properly
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
-        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
-        assertEquals(102, fs.getNextBlock(101));
-        assertEquals(103, fs.getNextBlock(102));
-        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(103));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
-
-        // And check the contents
-        it = stream.getBlockIterator();
-        count = 0;
-        while (it.hasNext()) {
-            ByteBuffer b = it.next();
-            data = new byte[512];
-            b.get(data);
+            // And check the contents
+            Iterator<ByteBuffer> it = stream.getBlockIterator();
+            int count = 0;
+            while (it.hasNext()) {
+                ByteBuffer b = it.next();
+                data = new byte[512];
+                b.get(data);
+                for (int i = 0; i < data.length; i++) {
+                    byte exp = (byte) (i % 256);
+                    assertEquals(exp, data[i]);
+                }
+                count++;
+            }
+            assertEquals(1, count);
+
+
+            // And a multi block one
+            data = new byte[512 * 3];
             for (int i = 0; i < data.length; i++) {
-                byte exp = (byte) (i % 256);
-                assertEquals(exp, data[i]);
+                data[i] = (byte) (i % 256);
             }
-            count++;
-        }
-        assertEquals(3, count);
 
-        // Free it
-        stream.free();
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
-        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
+            stream = new POIFSStream(fs);
+            stream.updateContents(data);
 
-        fs.close();
+            // Check it was allocated properly
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+            assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
+            assertEquals(102, fs.getNextBlock(101));
+            assertEquals(103, fs.getNextBlock(102));
+            assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(103));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
+
+            // And check the contents
+            it = stream.getBlockIterator();
+            count = 0;
+            while (it.hasNext()) {
+                ByteBuffer b = it.next();
+                data = new byte[512];
+                b.get(data);
+                for (int i = 0; i < data.length; i++) {
+                    byte exp = (byte) (i % 256);
+                    assertEquals(exp, data[i]);
+                }
+                count++;
+            }
+            assertEquals(3, count);
+
+            // Free it
+            stream.free();
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+            assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(100));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(104));
+        }
     }
 
     /**
@@ -550,40 +551,39 @@ final class TestPOIFSStream {
      */
     @Test
     void testWriteNewStreamExtraFATs() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"))) {
 
-        // Allocate almost all the blocks
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(127));
-        for (int i = 100; i < 127; i++) {
-            fs.setNextBlock(i, POIFSConstants.END_OF_CHAIN);
-        }
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(127));
-        assertTrue(fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
-
-
-        // Write a 3 block stream
-        byte[] data = new byte[512 * 3];
-        for (int i = 0; i < data.length; i++) {
-            data[i] = (byte) (i % 256);
-        }
-        POIFSStream stream = new POIFSStream(fs);
-        stream.updateContents(data);
-
-        // Check we got another BAT
-        assertFalse(fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
-        assertTrue(fs.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
-
-        // the BAT will be in the first spot of the new block
-        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(126));
-        assertEquals(129, fs.getNextBlock(127));
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(128));
-        assertEquals(130, fs.getNextBlock(129));
-        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(130));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(131));
+            // Allocate almost all the blocks
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(99));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(127));
+            for (int i = 100; i < 127; i++) {
+                fs.setNextBlock(i, POIFSConstants.END_OF_CHAIN);
+            }
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(127));
+            assertTrue(fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
+
+
+            // Write a 3 block stream
+            byte[] data = new byte[512 * 3];
+            for (int i = 0; i < data.length; i++) {
+                data[i] = (byte) (i % 256);
+            }
+            POIFSStream stream = new POIFSStream(fs);
+            stream.updateContents(data);
 
-        fs.close();
+            // Check we got another BAT
+            assertFalse(fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
+            assertTrue(fs.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
+
+            // the BAT will be in the first spot of the new block
+            assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(126));
+            assertEquals(129, fs.getNextBlock(127));
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(128));
+            assertEquals(130, fs.getNextBlock(129));
+            assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(130));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(131));
+        }
     }
 
     /**
@@ -592,54 +592,53 @@ final class TestPOIFSStream {
      */
     @Test
     void testWriteStream4096() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"))) {
+
+            // 0 -> 1 -> 2 -> end
+            assertEquals(1, fs.getNextBlock(0));
+            assertEquals(2, fs.getNextBlock(1));
+            assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
+            assertEquals(4, fs.getNextBlock(3));
 
-        // 0 -> 1 -> 2 -> end
-        assertEquals(1, fs.getNextBlock(0));
-        assertEquals(2, fs.getNextBlock(1));
-        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2));
-        assertEquals(4, fs.getNextBlock(3));
-
-        // First free one is at 15
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(14));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(15));
-
-
-        // Write a 5 block file
-        byte[] data = new byte[4096 * 5];
-        for (int i = 0; i < data.length; i++) {
-            data[i] = (byte) (i % 256);
-        }
-        POIFSStream stream = new POIFSStream(fs, 0);
-        stream.updateContents(data);
-
-
-        // Check it
-        assertEquals(1, fs.getNextBlock(0));
-        assertEquals(2, fs.getNextBlock(1));
-        assertEquals(15, fs.getNextBlock(2)); // Jumps
-        assertEquals(4, fs.getNextBlock(3));  // Next stream
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(14));
-        assertEquals(16, fs.getNextBlock(15)); // Continues
-        assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(16)); // Ends
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(17)); // Free
+            // First free one is at 15
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(14));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(15));
 
-        // Check the contents too
-        Iterator<ByteBuffer> it = stream.getBlockIterator();
-        int count = 0;
-        while (it.hasNext()) {
-            ByteBuffer b = it.next();
-            data = new byte[512];
-            b.get(data);
+
+            // Write a 5 block file
+            byte[] data = new byte[4096 * 5];
             for (int i = 0; i < data.length; i++) {
-                byte exp = (byte) (i % 256);
-                assertEquals(exp, data[i]);
+                data[i] = (byte) (i % 256);
             }
-            count++;
-        }
-        assertEquals(5, count);
+            POIFSStream stream = new POIFSStream(fs, 0);
+            stream.updateContents(data);
+
 
-        fs.close();
+            // Check it
+            assertEquals(1, fs.getNextBlock(0));
+            assertEquals(2, fs.getNextBlock(1));
+            assertEquals(15, fs.getNextBlock(2)); // Jumps
+            assertEquals(4, fs.getNextBlock(3));  // Next stream
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(14));
+            assertEquals(16, fs.getNextBlock(15)); // Continues
+            assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(16)); // Ends
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(17)); // Free
+
+            // Check the contents too
+            Iterator<ByteBuffer> it = stream.getBlockIterator();
+            int count = 0;
+            while (it.hasNext()) {
+                ByteBuffer b = it.next();
+                data = new byte[512];
+                b.get(data);
+                for (int i = 0; i < data.length; i++) {
+                    byte exp = (byte) (i % 256);
+                    assertEquals(exp, data[i]);
+                }
+                count++;
+            }
+            assertEquals(5, count);
+        }
     }
 
     /**
@@ -933,191 +932,192 @@ final class TestPOIFSStream {
      */
     @Test
     void testWriteThenReplace() throws Exception {
-        POIFSFileSystem fs = new POIFSFileSystem();
+        try (POIFSFileSystem fs1 = new POIFSFileSystem()) {
+
+            // Starts empty, other that Properties and BAT
+            BATBlock bat = fs1.getBATBlockAndIndex(0).getBlock();
+            assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(2));
+
+            // Write something that uses a main stream
+            byte[] main4106 = new byte[4106];
+            main4106[0] = -10;
+            main4106[4105] = -11;
+            fs1.getRoot().createDocument("Normal", new ByteArrayInputStream(main4106));
+
+            // Should have used 9 blocks
+            assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
+            assertEquals(3, bat.getValueAt(2));
+            assertEquals(4, bat.getValueAt(3));
+            assertEquals(5, bat.getValueAt(4));
+            assertEquals(6, bat.getValueAt(5));
+            assertEquals(7, bat.getValueAt(6));
+            assertEquals(8, bat.getValueAt(7));
+            assertEquals(9, bat.getValueAt(8));
+            assertEquals(10, bat.getValueAt(9));
+            assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
+
+            DocumentEntry normal = (DocumentEntry) fs1.getRoot().getEntry("Normal");
+            assertEquals(4106, normal.getSize());
+            assertEquals(4106, ((DocumentNode) normal).getProperty().getSize());
+
+
+            // Replace with one still big enough for a main stream, but one block smaller
+            byte[] main4096 = new byte[4096];
+            main4096[0] = -10;
+            main4096[4095] = -11;
+
+            try (DocumentOutputStream nout = new DocumentOutputStream(normal)) {
+                nout.write(main4096);
+            }
 
-        // Starts empty, other that Properties and BAT
-        BATBlock bat = fs.getBATBlockAndIndex(0).getBlock();
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(2));
-
-        // Write something that uses a main stream
-        byte[] main4106 = new byte[4106];
-        main4106[0] = -10;
-        main4106[4105] = -11;
-        fs.getRoot().createDocument("Normal", new ByteArrayInputStream(main4106));
-
-        // Should have used 9 blocks
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
-        assertEquals(3, bat.getValueAt(2));
-        assertEquals(4, bat.getValueAt(3));
-        assertEquals(5, bat.getValueAt(4));
-        assertEquals(6, bat.getValueAt(5));
-        assertEquals(7, bat.getValueAt(6));
-        assertEquals(8, bat.getValueAt(7));
-        assertEquals(9, bat.getValueAt(8));
-        assertEquals(10, bat.getValueAt(9));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
-
-        DocumentEntry normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        assertEquals(4106, normal.getSize());
-        assertEquals(4106, ((DocumentNode) normal).getProperty().getSize());
-
-
-        // Replace with one still big enough for a main stream, but one block smaller
-        byte[] main4096 = new byte[4096];
-        main4096[0] = -10;
-        main4096[4095] = -11;
-
-        DocumentOutputStream nout = new DocumentOutputStream(normal);
-        nout.write(main4096);
-        nout.close();
-
-        // Will have dropped to 8
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
-        assertEquals(3, bat.getValueAt(2));
-        assertEquals(4, bat.getValueAt(3));
-        assertEquals(5, bat.getValueAt(4));
-        assertEquals(6, bat.getValueAt(5));
-        assertEquals(7, bat.getValueAt(6));
-        assertEquals(8, bat.getValueAt(7));
-        assertEquals(9, bat.getValueAt(8));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
-
-        normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        assertEquals(4096, normal.getSize());
-        assertEquals(4096, ((DocumentNode) normal).getProperty().getSize());
-
-
-        // Write and check
-        fs = writeOutAndReadBack(fs);
-        bat = fs.getBATBlockAndIndex(0).getBlock();
-
-        // No change after write
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); // Properties
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
-        assertEquals(3, bat.getValueAt(2));
-        assertEquals(4, bat.getValueAt(3));
-        assertEquals(5, bat.getValueAt(4));
-        assertEquals(6, bat.getValueAt(5));
-        assertEquals(7, bat.getValueAt(6));
-        assertEquals(8, bat.getValueAt(7));
-        assertEquals(9, bat.getValueAt(8));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9)); // End of Normal
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
-
-        normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        assertEquals(4096, normal.getSize());
-        assertEquals(4096, ((DocumentNode) normal).getProperty().getSize());
-
-
-        // Make longer, take 1 block at the end
-        normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        nout = new DocumentOutputStream(normal);
-        nout.write(main4106);
-        nout.close();
-
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
-        assertEquals(3, bat.getValueAt(2));
-        assertEquals(4, bat.getValueAt(3));
-        assertEquals(5, bat.getValueAt(4));
-        assertEquals(6, bat.getValueAt(5));
-        assertEquals(7, bat.getValueAt(6));
-        assertEquals(8, bat.getValueAt(7));
-        assertEquals(9, bat.getValueAt(8));
-        assertEquals(10, bat.getValueAt(9));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Normal
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
-
-        normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        assertEquals(4106, normal.getSize());
-        assertEquals(4106, ((DocumentNode) normal).getProperty().getSize());
-
-
-        // Make it small, will trigger the SBAT stream and free lots up
-        byte[] mini = new byte[]{42, 0, 1, 2, 3, 4, 42};
-        normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        nout = new DocumentOutputStream(normal);
-        nout.write(mini);
-        nout.close();
-
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(4));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(5));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(6));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(7));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(8));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(9));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
-
-        normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        assertEquals(7, normal.getSize());
-        assertEquals(7, ((DocumentNode) normal).getProperty().getSize());
-
-
-        // Finally back to big again
-        nout = new DocumentOutputStream(normal);
-        nout.write(main4096);
-        nout.close();
-
-        // Will keep the mini stream, now empty
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
-        assertEquals(5, bat.getValueAt(4));
-        assertEquals(6, bat.getValueAt(5));
-        assertEquals(7, bat.getValueAt(6));
-        assertEquals(8, bat.getValueAt(7));
-        assertEquals(9, bat.getValueAt(8));
-        assertEquals(10, bat.getValueAt(9));
-        assertEquals(11, bat.getValueAt(10));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13));
-
-        normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        assertEquals(4096, normal.getSize());
-        assertEquals(4096, ((DocumentNode) normal).getProperty().getSize());
-
-
-        // Save, re-load, re-check
-        fs = writeOutAndReadBack(fs);
-        bat = fs.getBATBlockAndIndex(0).getBlock();
-
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
-        assertEquals(5, bat.getValueAt(4));
-        assertEquals(6, bat.getValueAt(5));
-        assertEquals(7, bat.getValueAt(6));
-        assertEquals(8, bat.getValueAt(7));
-        assertEquals(9, bat.getValueAt(8));
-        assertEquals(10, bat.getValueAt(9));
-        assertEquals(11, bat.getValueAt(10));
-        assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13));
-
-        normal = (DocumentEntry) fs.getRoot().getEntry("Normal");
-        assertEquals(4096, normal.getSize());
-        assertEquals(4096, ((DocumentNode) normal).getProperty().getSize());
+            // Will have dropped to 8
+            assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
+            assertEquals(3, bat.getValueAt(2));
+            assertEquals(4, bat.getValueAt(3));
+            assertEquals(5, bat.getValueAt(4));
+            assertEquals(6, bat.getValueAt(5));
+            assertEquals(7, bat.getValueAt(6));
+            assertEquals(8, bat.getValueAt(7));
+            assertEquals(9, bat.getValueAt(8));
+            assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
+
+            normal = (DocumentEntry) fs1.getRoot().getEntry("Normal");
+            assertEquals(4096, normal.getSize());
+            assertEquals(4096, ((DocumentNode) normal).getProperty().getSize());
+
+
+            // Write and check
+            try (POIFSFileSystem fs2 = writeOutAndReadBack(fs1)) {
+                bat = fs2.getBATBlockAndIndex(0).getBlock();
+
+                // No change after write
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0)); // Properties
+                assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
+                assertEquals(3, bat.getValueAt(2));
+                assertEquals(4, bat.getValueAt(3));
+                assertEquals(5, bat.getValueAt(4));
+                assertEquals(6, bat.getValueAt(5));
+                assertEquals(7, bat.getValueAt(6));
+                assertEquals(8, bat.getValueAt(7));
+                assertEquals(9, bat.getValueAt(8));
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(9)); // End of Normal
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
+
+                normal = (DocumentEntry) fs2.getRoot().getEntry("Normal");
+                assertEquals(4096, normal.getSize());
+                assertEquals(4096, ((DocumentNode) normal).getProperty().getSize());
+
+
+                // Make longer, take 1 block at the end
+                normal = (DocumentEntry) fs2.getRoot().getEntry("Normal");
+                try (DocumentOutputStream nout = new DocumentOutputStream(normal)) {
+                    nout.write(main4106);
+                }
+
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+                assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
+                assertEquals(3, bat.getValueAt(2));
+                assertEquals(4, bat.getValueAt(3));
+                assertEquals(5, bat.getValueAt(4));
+                assertEquals(6, bat.getValueAt(5));
+                assertEquals(7, bat.getValueAt(6));
+                assertEquals(8, bat.getValueAt(7));
+                assertEquals(9, bat.getValueAt(8));
+                assertEquals(10, bat.getValueAt(9));
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(10)); // Normal
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
+
+                normal = (DocumentEntry) fs2.getRoot().getEntry("Normal");
+                assertEquals(4106, normal.getSize());
+                assertEquals(4106, ((DocumentNode) normal).getProperty().getSize());
+
+
+                // Make it small, will trigger the SBAT stream and free lots up
+                byte[] mini = new byte[]{42, 0, 1, 2, 3, 4, 42};
+                normal = (DocumentEntry) fs2.getRoot().getEntry("Normal");
+                try (DocumentOutputStream nout = new DocumentOutputStream(normal)) {
+                    nout.write(mini);
+                }
+
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+                assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(4));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(5));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(6));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(7));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(8));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(9));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(10));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(11));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
+
+                normal = (DocumentEntry) fs2.getRoot().getEntry("Normal");
+                assertEquals(7, normal.getSize());
+                assertEquals(7, ((DocumentNode) normal).getProperty().getSize());
+
+
+                // Finally back to big again
+                try (DocumentOutputStream nout = new DocumentOutputStream(normal)) {
+                    nout.write(main4096);
+                }
 
-        fs.close();
+                // Will keep the mini stream, now empty
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+                assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
+                assertEquals(5, bat.getValueAt(4));
+                assertEquals(6, bat.getValueAt(5));
+                assertEquals(7, bat.getValueAt(6));
+                assertEquals(8, bat.getValueAt(7));
+                assertEquals(9, bat.getValueAt(8));
+                assertEquals(10, bat.getValueAt(9));
+                assertEquals(11, bat.getValueAt(10));
+                assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
+                assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13));
+
+                normal = (DocumentEntry) fs2.getRoot().getEntry("Normal");
+                assertEquals(4096, normal.getSize());
+                assertEquals(4096, ((DocumentNode) normal).getProperty().getSize());
+
+
+                // Save, re-load, re-check
+                try (POIFSFileSystem fs3 = writeOutAndReadBack(fs2)) {
+                    bat = fs3.getBATBlockAndIndex(0).getBlock();
+
+                    assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(0));
+                    assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, bat.getValueAt(1));
+                    assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(2)); // SBAT
+                    assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(3)); // Mini Stream
+                    assertEquals(5, bat.getValueAt(4));
+                    assertEquals(6, bat.getValueAt(5));
+                    assertEquals(7, bat.getValueAt(6));
+                    assertEquals(8, bat.getValueAt(7));
+                    assertEquals(9, bat.getValueAt(8));
+                    assertEquals(10, bat.getValueAt(9));
+                    assertEquals(11, bat.getValueAt(10));
+                    assertEquals(POIFSConstants.END_OF_CHAIN, bat.getValueAt(11));
+                    assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(12));
+                    assertEquals(POIFSConstants.UNUSED_BLOCK, bat.getValueAt(13));
+
+                    normal = (DocumentEntry) fs3.getRoot().getEntry("Normal");
+                    assertEquals(4096, normal.getSize());
+                    assertEquals(4096, ((DocumentNode) normal).getProperty().getSize());
+                }
+            }
+        }
     }
 
 
@@ -1125,14 +1125,43 @@ final class TestPOIFSStream {
      * Returns test files with 512 byte and 4k block sizes, loaded
      * both from InputStreams and Files
      */
-    private POIFSFileSystem[] get512and4kFileAndInput() throws IOException {
-        POIFSFileSystem fsA = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
-        POIFSFileSystem fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
-        POIFSFileSystem fsC = new POIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
-        POIFSFileSystem fsD = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
-        return new POIFSFileSystem[]{fsA, fsB, fsC, fsD};
+    public static Collection<Arguments> get512and4kFileAndInput() {
+        return CollectionUtils.union(get512FileAndInput(), get4kFileAndInput());
     }
 
+    public static List<Arguments> get512FileAndInput() {
+        return Arrays.asList(
+            Arguments.of("BlockSize512.zvi", (Function<String,POIFSFileSystem>)TestPOIFSStream::openAsFile),
+            Arguments.of("BlockSize512.zvi", (Function<String,POIFSFileSystem>)TestPOIFSStream::openAsStream)
+        );
+    }
+
+    public static List<Arguments> get4kFileAndInput() {
+        return Arrays.asList(
+            Arguments.of("BlockSize4096.zvi", (Function<String,POIFSFileSystem>)TestPOIFSStream::openAsFile),
+            Arguments.of("BlockSize4096.zvi", (Function<String,POIFSFileSystem>)TestPOIFSStream::openAsStream)
+        );
+    }
+
+    private static POIFSFileSystem openAsFile(String fileName) {
+        try {
+            return new POIFSFileSystem(_inst.getFile(fileName));
+        } catch (IOException e) {
+            fail(e);
+            return null;
+        }
+    }
+
+    private static POIFSFileSystem openAsStream(String fileName) {
+        try {
+            return new POIFSFileSystem(_inst.openResourceAsStream(fileName));
+        } catch (IOException e) {
+            fail(e);
+            return null;
+        }
+    }
+
+
     private static void assertBATCount(POIFSFileSystem fs, int expectedBAT, int expectedXBAT) throws IOException {
         int foundBAT = 0;
         int foundXBAT = 0;
@@ -1161,16 +1190,9 @@ final class TestPOIFSStream {
     }
 
     private static HeaderBlock writeOutAndReadHeader(POIFSFileSystem fs) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream();
         fs.writeFilesystem(baos);
-
-        return new HeaderBlock(new ByteArrayInputStream(baos.toByteArray()));
-    }
-
-    private static POIFSFileSystem writeOutAndReadBack(POIFSFileSystem original) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        original.writeFilesystem(baos);
-        return new POIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
+        return new HeaderBlock(baos.toInputStream());
     }
 
     private static POIFSFileSystem writeOutFileAndReadBack(POIFSFileSystem original) throws IOException {
@@ -1181,37 +1203,29 @@ final class TestPOIFSStream {
         return new POIFSFileSystem(file, false);
     }
 
-    @Test
-    void basicOpen() throws IOException {
-        POIFSFileSystem fsA, fsB;
-
+    @ParameterizedTest()
+    @MethodSource("get512FileAndInput")
+    void basicOpen512(String file, Function<String,POIFSFileSystem> opener) throws IOException {
         // With a simple 512 block file
-        fsA = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
-        fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
-        for (POIFSFileSystem fs : new POIFSFileSystem[]{fsA, fsB}) {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             assertEquals(512, fs.getBigBlockSize());
         }
-        fsA.close();
-        fsB.close();
+    }
 
+    @ParameterizedTest()
+    @MethodSource("get4kFileAndInput")
+    void basicOpen4k(String file, Function<String,POIFSFileSystem> opener) throws IOException {
         // Now with a simple 4096 block file
-        fsA = new POIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
-        fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
-        for (POIFSFileSystem fs : new POIFSFileSystem[]{fsA, fsB}) {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             assertEquals(4096, fs.getBigBlockSize());
         }
-        fsA.close();
-        fsB.close();
     }
 
-    @Test
-    void propertiesAndFatOnRead() throws IOException {
-        POIFSFileSystem fsA, fsB;
-
+    @ParameterizedTest()
+    @MethodSource("get512FileAndInput")
+    void propertiesAndFatOnRead512(String file, Function<String,POIFSFileSystem> opener) throws IOException {
         // With a simple 512 block file
-        fsA = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
-        fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
-        for (POIFSFileSystem fs : new POIFSFileSystem[]{fsA, fsB}) {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             // Check the FAT was properly processed:
             // Verify we only got one block
             fs.getBATBlockAndIndex(0);
@@ -1266,14 +1280,14 @@ final class TestPOIFSStream {
                 assertEquals(i + 1, ministore.getNextBlock(i));
             }
             assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(50));
-
-            fs.close();
         }
+    }
 
+    @ParameterizedTest()
+    @MethodSource("get4kFileAndInput")
+    void propertiesAndFatOnRead4k(String file, Function<String,POIFSFileSystem> opener) throws IOException {
         // Now with a simple 4096 block file
-        fsA = new POIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
-        fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
-        for (POIFSFileSystem fs : new POIFSFileSystem[]{fsA, fsB}) {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             // Check the FAT was properly processed
             // Verify we only got one block
             fs.getBATBlockAndIndex(0);
@@ -1330,8 +1344,6 @@ final class TestPOIFSStream {
                 assertEquals(i + 1, ministore.getNextBlock(i));
             }
             assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(50));
-
-            fs.close();
         }
     }
 
@@ -1339,11 +1351,10 @@ final class TestPOIFSStream {
      * Check that for a given block, we can correctly figure
      * out what the next one is
      */
-    @Test
-    void nextBlock() throws IOException {
-        POIFSFileSystem fsA = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
-        POIFSFileSystem fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
-        for (POIFSFileSystem fs : new POIFSFileSystem[]{fsA, fsB}) {
+    @ParameterizedTest()
+    @MethodSource("get512FileAndInput")
+    void nextBlock512(String file, Function<String,POIFSFileSystem> opener) throws IOException {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             // 0 -> 21 are simple
             for (int i = 0; i < 21; i++) {
                 assertEquals(i + 1, fs.getNextBlock(i));
@@ -1375,14 +1386,14 @@ final class TestPOIFSStream {
             for (int i = 100; i < fs.getBigBlockSizeDetails().getBATEntriesPerBlock(); i++) {
                 assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(i));
             }
-
-            fs.close();
         }
+    }
 
+    @ParameterizedTest()
+    @MethodSource("get4kFileAndInput")
+    void nextBlock4k(String file, Function<String,POIFSFileSystem> opener) throws IOException {
         // Quick check on 4096 byte blocks too
-        fsA = new POIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
-        fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
-        for (POIFSFileSystem fs : new POIFSFileSystem[]{fsA, fsB}) {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             // 0 -> 1 -> 2 -> end
             assertEquals(1, fs.getNextBlock(0));
             assertEquals(2, fs.getNextBlock(1));
@@ -1393,23 +1404,18 @@ final class TestPOIFSStream {
                 assertEquals(i + 1, fs.getNextBlock(i));
             }
             assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(11));
-
-            fs.close();
         }
     }
 
     /**
      * Check we get the right data back for each block
      */
-    @Test
-    void getBlock() throws IOException {
-        POIFSFileSystem fsA = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
-        POIFSFileSystem fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
-        for (POIFSFileSystem fs : new POIFSFileSystem[]{fsA, fsB}) {
-            ByteBuffer b;
-
+    @ParameterizedTest()
+    @MethodSource("get512FileAndInput")
+    void getBlock512(String file, Function<String,POIFSFileSystem> opener) throws IOException {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             // The 0th block is the first data block
-            b = fs.getBlockAt(0);
+            ByteBuffer b = fs.getBlockAt(0);
             assertEquals((byte) 0x9e, b.get());
             assertEquals((byte) 0x75, b.get());
             assertEquals((byte) 0x97, b.get());
@@ -1432,18 +1438,16 @@ final class TestPOIFSStream {
             assertEquals((byte) 0x00, b.get());
             assertEquals((byte) 0x00, b.get());
             assertEquals((byte) 0x00, b.get());
-
-            fs.close();
         }
+    }
 
+    @ParameterizedTest()
+    @MethodSource("get4kFileAndInput")
+    void getBlock4k(String file, Function<String,POIFSFileSystem> opener) throws IOException {
         // Quick check on 4096 byte blocks too
-        fsA = new POIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
-        fsB = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
-        for (POIFSFileSystem fs : new POIFSFileSystem[]{fsA, fsB}) {
-            ByteBuffer b;
-
+        try (POIFSFileSystem fs = opener.apply(file)) {
             // The 0th block is the first data block
-            b = fs.getBlockAt(0);
+            ByteBuffer b = fs.getBlockAt(0);
             assertEquals((byte) 0x9e, b.get());
             assertEquals((byte) 0x75, b.get());
             assertEquals((byte) 0x97, b.get());
@@ -1466,8 +1470,6 @@ final class TestPOIFSStream {
             assertEquals((byte) 0x00, b.get());
             assertEquals((byte) 0x00, b.get());
             assertEquals((byte) 0x00, b.get());
-
-            fs.close();
         }
     }
 
@@ -1477,29 +1479,26 @@ final class TestPOIFSStream {
      */
     @Test
     void getFreeBlockWithSpare() throws IOException {
-        POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
-
-        // Our first BAT block has spares
-        assertTrue(fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
-
-        // First free one is 100
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
-
-        // Ask, will get 100
-        assertEquals(100, fs.getFreeBlock());
-
-        // Ask again, will still get 100 as not written to
-        assertEquals(100, fs.getFreeBlock());
-
-        // Allocate it, then ask again
-        fs.setNextBlock(100, POIFSConstants.END_OF_CHAIN);
-        assertEquals(101, fs.getFreeBlock());
+        try (POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi"))) {
+            // Our first BAT block has spares
+            assertTrue(fs.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
 
-        // All done
-        fs.close();
+            // First free one is 100
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(100));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(101));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(102));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(103));
+
+            // Ask, will get 100
+            assertEquals(100, fs.getFreeBlock());
+
+            // Ask again, will still get 100 as not written to
+            assertEquals(100, fs.getFreeBlock());
+
+            // Allocate it, then ask again
+            fs.setNextBlock(100, POIFSConstants.END_OF_CHAIN);
+            assertEquals(101, fs.getFreeBlock());
+        }
     }
 
     /**
@@ -1508,136 +1507,134 @@ final class TestPOIFSStream {
      */
     @Test
     void getFreeBlockWithNoneSpare() throws IOException {
-        POIFSFileSystem fs1 = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
-        int free;
+        try (POIFSFileSystem fs1 = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"))) {
+            int free;
 
-        // We have one BAT at block 99
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(99));
-        assertBATCount(fs1, 1, 0);
+            // We have one BAT at block 99
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(99));
+            assertBATCount(fs1, 1, 0);
 
-        // We've spare ones from 100 to 128
-        for (int i = 100; i < 128; i++) {
-            assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(i));
-        }
+            // We've spare ones from 100 to 128
+            for (int i = 100; i < 128; i++) {
+                assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(i));
+            }
 
-        // Check our BAT knows it's free
-        assertTrue(fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
+            // Check our BAT knows it's free
+            assertTrue(fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
 
-        // Allocate all the spare ones
-        for (int i = 100; i < 128; i++) {
-            fs1.setNextBlock(i, POIFSConstants.END_OF_CHAIN);
-        }
+            // Allocate all the spare ones
+            for (int i = 100; i < 128; i++) {
+                fs1.setNextBlock(i, POIFSConstants.END_OF_CHAIN);
+            }
 
-        // BAT is now full, but there's only the one
-        assertFalse(fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
-        assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(128), "Should only be one BAT");
-        assertBATCount(fs1, 1, 0);
+            // BAT is now full, but there's only the one
+            assertFalse(fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
+            assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(128), "Should only be one BAT");
+            assertBATCount(fs1, 1, 0);
 
 
-        // Now ask for a free one, will need to extend the file
-        assertEquals(129, fs1.getFreeBlock());
+            // Now ask for a free one, will need to extend the file
+            assertEquals(129, fs1.getFreeBlock());
 
-        assertFalse(fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
-        assertTrue(fs1.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
-        assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(128));
-        assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(129));
+            assertFalse(fs1.getBATBlockAndIndex(0).getBlock().hasFreeSectors());
+            assertTrue(fs1.getBATBlockAndIndex(128).getBlock().hasFreeSectors());
+            assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs1.getNextBlock(128));
+            assertEquals(POIFSConstants.UNUSED_BLOCK, fs1.getNextBlock(129));
 
-        // We now have 2 BATs, but no XBATs
-        assertBATCount(fs1, 2, 0);
+            // We now have 2 BATs, but no XBATs
+            assertBATCount(fs1, 2, 0);
 
 
-        // Fill up to hold 109 BAT blocks
-        for (int i = 0; i < 109; i++) {
-            fs1.getFreeBlock();
-            int startOffset = i * 128;
-            while (fs1.getBATBlockAndIndex(startOffset).getBlock().hasFreeSectors()) {
-                free = fs1.getFreeBlock();
-                fs1.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
+            // Fill up to hold 109 BAT blocks
+            for (int i = 0; i < 109; i++) {
+                fs1.getFreeBlock();
+                int startOffset = i * 128;
+                while (fs1.getBATBlockAndIndex(startOffset).getBlock().hasFreeSectors()) {
+                    free = fs1.getFreeBlock();
+                    fs1.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
+                }
             }
-        }
 
-        assertFalse(fs1.getBATBlockAndIndex(109 * 128 - 1).getBlock().hasFreeSectors());
-        assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(109 * 128), "Should only be 109 BATs");
+            assertFalse(fs1.getBATBlockAndIndex(109 * 128 - 1).getBlock().hasFreeSectors());
+            assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(109 * 128), "Should only be 109 BATs");
 
-        // We now have 109 BATs, but no XBATs
-        assertBATCount(fs1, 109, 0);
+            // We now have 109 BATs, but no XBATs
+            assertBATCount(fs1, 109, 0);
 
 
-        // Ask for it to be written out, and check the header
-        HeaderBlock header = writeOutAndReadHeader(fs1);
-        assertEquals(109, header.getBATCount());
-        assertEquals(0, header.getXBATCount());
+            // Ask for it to be written out, and check the header
+            HeaderBlock header = writeOutAndReadHeader(fs1);
+            assertEquals(109, header.getBATCount());
+            assertEquals(0, header.getXBATCount());
 
 
-        // Ask for another, will get our first XBAT
-        free = fs1.getFreeBlock();
-        assertTrue(free > 0, "Had: " + free);
+            // Ask for another, will get our first XBAT
+            free = fs1.getFreeBlock();
+            assertTrue(free > 0, "Had: " + free);
 
-        assertFalse(fs1.getBATBlockAndIndex(109 * 128 - 1).getBlock().hasFreeSectors());
-        assertTrue(fs1.getBATBlockAndIndex(110 * 128 - 1).getBlock().hasFreeSectors());
-        assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(110 * 128), "Should only be 110 BATs");
-        assertBATCount(fs1, 110, 1);
+            assertFalse(fs1.getBATBlockAndIndex(109 * 128 - 1).getBlock().hasFreeSectors());
+            assertTrue(fs1.getBATBlockAndIndex(110 * 128 - 1).getBlock().hasFreeSectors());
+            assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(110 * 128), "Should only be 110 BATs");
+            assertBATCount(fs1, 110, 1);
 
-        header = writeOutAndReadHeader(fs1);
-        assertEquals(110, header.getBATCount());
-        assertEquals(1, header.getXBATCount());
+            header = writeOutAndReadHeader(fs1);
+            assertEquals(110, header.getBATCount());
+            assertEquals(1, header.getXBATCount());
 
 
-        // Fill the XBAT, which means filling 127 BATs
-        for (int i = 109; i < 109 + 127; i++) {
-            fs1.getFreeBlock();
-            int startOffset = i * 128;
-            while (fs1.getBATBlockAndIndex(startOffset).getBlock().hasFreeSectors()) {
-                free = fs1.getFreeBlock();
-                fs1.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
+            // Fill the XBAT, which means filling 127 BATs
+            for (int i = 109; i < 109 + 127; i++) {
+                fs1.getFreeBlock();
+                int startOffset = i * 128;
+                while (fs1.getBATBlockAndIndex(startOffset).getBlock().hasFreeSectors()) {
+                    free = fs1.getFreeBlock();
+                    fs1.setNextBlock(free, POIFSConstants.END_OF_CHAIN);
+                }
+                assertBATCount(fs1, i + 1, 1);
             }
-            assertBATCount(fs1, i + 1, 1);
-        }
-
-        // Should now have 109+127 = 236 BATs
-        assertFalse(fs1.getBATBlockAndIndex(236 * 128 - 1).getBlock().hasFreeSectors());
-        assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(236 * 128), "Should only be 236 BATs");
-        assertBATCount(fs1, 236, 1);
-
 
-        // Ask for another, will get our 2nd XBAT
-        free = fs1.getFreeBlock();
-        assertTrue(free > 0, "Had: " + free);
+            // Should now have 109+127 = 236 BATs
+            assertFalse(fs1.getBATBlockAndIndex(236 * 128 - 1).getBlock().hasFreeSectors());
+            assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(236 * 128), "Should only be 236 BATs");
+            assertBATCount(fs1, 236, 1);
 
-        assertFalse(fs1.getBATBlockAndIndex(236 * 128 - 1).getBlock().hasFreeSectors());
-        assertTrue(fs1.getBATBlockAndIndex(237 * 128 - 1).getBlock().hasFreeSectors());
-        assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(237 * 128), "Should only be 237 BATs");
 
+            // Ask for another, will get our 2nd XBAT
+            free = fs1.getFreeBlock();
+            assertTrue(free > 0, "Had: " + free);
 
-        // Check the counts now
-        assertBATCount(fs1, 237, 2);
+            assertFalse(fs1.getBATBlockAndIndex(236 * 128 - 1).getBlock().hasFreeSectors());
+            assertTrue(fs1.getBATBlockAndIndex(237 * 128 - 1).getBlock().hasFreeSectors());
+            assertThrows(IndexOutOfBoundsException.class, () -> fs1.getBATBlockAndIndex(237 * 128), "Should only be 237 BATs");
 
-        // Check the header
-        header = writeOutAndReadHeader(fs1);
-        assertNotNull(header);
+            // Check the counts now
+            assertBATCount(fs1, 237, 2);
 
-        // Now, write it out, and read it back in again fully
-        POIFSFileSystem fs2 = writeOutAndReadBack(fs1);
-        fs1.close();
+            // Check the header
+            header = writeOutAndReadHeader(fs1);
+            assertNotNull(header);
 
-        // Check that it is seen correctly
-        assertBATCount(fs2, 237, 2);
+            // Now, write it out, and read it back in again fully
+            try (POIFSFileSystem fs2 = writeOutAndReadBack(fs1)) {
 
-        assertFalse(fs2.getBATBlockAndIndex(236 * 128 - 1).getBlock().hasFreeSectors());
-        assertTrue(fs2.getBATBlockAndIndex(237 * 128 - 1).getBlock().hasFreeSectors());
-        assertThrows(IndexOutOfBoundsException.class, () -> fs2.getBATBlockAndIndex(237 * 128), "Should only be 237 BATs");
+                // Check that it is seen correctly
+                assertBATCount(fs2, 237, 2);
 
-        // All done
-        fs2.close();
+                assertFalse(fs2.getBATBlockAndIndex(236 * 128 - 1).getBlock().hasFreeSectors());
+                assertTrue(fs2.getBATBlockAndIndex(237 * 128 - 1).getBlock().hasFreeSectors());
+                assertThrows(IndexOutOfBoundsException.class, () -> fs2.getBATBlockAndIndex(237 * 128), "Should only be 237 BATs");
+            }
+        }
     }
 
     /**
      * Test that we can correctly get the list of directory
      * entries, and the details on the files in them
      */
-    @Test
-    void listEntries() throws IOException {
-        for (POIFSFileSystem fs : get512and4kFileAndInput()) {
+    @ParameterizedTest
+    @MethodSource("get512and4kFileAndInput")
+    void listEntries(String file, Function<String,POIFSFileSystem> opener) throws IOException {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             DirectoryEntry root = fs.getRoot();
             assertEquals(5, root.getEntryCount());
 
@@ -1665,8 +1662,6 @@ final class TestPOIFSStream {
             // Look inside another
             DirectoryEntry imageD = (DirectoryEntry) image;
             assertEquals(7, imageD.getEntryCount());
-
-            fs.close();
         }
     }
 
@@ -1674,9 +1669,11 @@ final class TestPOIFSStream {
      * Tests that we can get the correct contents for
      * a document in the filesystem
      */
-    @Test
-    void getDocumentEntry() throws Exception {
-        for (POIFSFileSystem fs : get512and4kFileAndInput()) {
+    @ParameterizedTest
+    @MethodSource("get512and4kFileAndInput")
+    void getDocumentEntry(String file, Function<String,POIFSFileSystem> opener)
+    throws IOException, NoPropertySetStreamException {
+        try (POIFSFileSystem fs = opener.apply(file)) {
             DirectoryEntry root = fs.getRoot();
             Entry si = root.getEntry("\u0005SummaryInformation");
 
@@ -1687,18 +1684,16 @@ final class TestPOIFSStream {
             assertContentsMatches(null, doc);
 
             // Now try to build the property set
-            DocumentInputStream inp = new DocumentInputStream(doc);
-            PropertySet ps = PropertySetFactory.create(inp);
-            SummaryInformation inf = (SummaryInformation) ps;
-
-            // Check some bits in it
-            assertNull(inf.getApplicationName());
-            assertNull(inf.getAuthor());
-            assertNull(inf.getSubject());
-            assertEquals(131333, inf.getOSVersion());
-
-            // Finish with this one
-            inp.close();
+            try (DocumentInputStream inp = new DocumentInputStream(doc)) {
+                PropertySet ps = PropertySetFactory.create(inp);
+                SummaryInformation inf = (SummaryInformation) ps;
+
+                // Check some bits in it
+                assertNull(inf.getApplicationName());
+                assertNull(inf.getAuthor());
+                assertNull(inf.getSubject());
+                assertEquals(131333, inf.getOSVersion());
+            }
 
 
             // Try the other summary information
@@ -1707,12 +1702,11 @@ final class TestPOIFSStream {
             doc = (DocumentNode) si;
             assertContentsMatches(null, doc);
 
-            inp = new DocumentInputStream(doc);
-            ps = PropertySetFactory.create(inp);
-            DocumentSummaryInformation dinf = (DocumentSummaryInformation) ps;
-            assertEquals(131333, dinf.getOSVersion());
-
-            fs.close();
+            try (DocumentInputStream inp = new DocumentInputStream(doc)) {
+                PropertySet ps = PropertySetFactory.create(inp);
+                DocumentSummaryInformation dinf = (DocumentSummaryInformation) ps;
+                assertEquals(131333, dinf.getOSVersion());
+            }
         }
     }
 
@@ -1720,13 +1714,14 @@ final class TestPOIFSStream {
      * Read a file, write it and read it again.
      * Then, alter+add some streams, write and read
      */
-    @Test
-    void readWriteRead() throws Exception {
+    @ParameterizedTest
+    @MethodSource("get512and4kFileAndInput")
+    void readWriteRead(String file, Function<String,POIFSFileSystem> opener) throws IOException, NoPropertySetStreamException {
         SummaryInformation sinf;
         DocumentSummaryInformation dinf;
         DirectoryEntry root, testDir;
 
-        for (POIFSFileSystem fs1 : get512and4kFileAndInput()) {
+        try (POIFSFileSystem fs1 = opener.apply(file)) {
             // Check we can find the entries we expect
             root = fs1.getRoot();
             assertEquals(5, root.getEntryCount());
@@ -1736,788 +1731,764 @@ final class TestPOIFSStream {
             assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
             assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
 
-
             // Write out, re-load
-            POIFSFileSystem fs2 = writeOutAndReadBack(fs1);
-            fs1.close();
-
-            // Check they're still there
-            root = fs2.getRoot();
-            assertEquals(5, root.getEntryCount());
-            assertThat(root.getEntryNames(), hasItem("Thumbnail"));
-            assertThat(root.getEntryNames(), hasItem("Image"));
-            assertThat(root.getEntryNames(), hasItem("Tags"));
-            assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
-            assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
+            try (POIFSFileSystem fs2 = writeOutAndReadBack(fs1)) {
+                // Check they're still there
+                root = fs2.getRoot();
+                assertEquals(5, root.getEntryCount());
+                assertThat(root.getEntryNames(), hasItem("Thumbnail"));
+                assertThat(root.getEntryNames(), hasItem("Image"));
+                assertThat(root.getEntryNames(), hasItem("Tags"));
+                assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
+                assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
+
+
+                // Check the contents of them - parse the summary block and check
+                sinf = (SummaryInformation) PropertySetFactory.create(new DocumentInputStream(
+                    (DocumentEntry) root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
+                assertEquals(131333, sinf.getOSVersion());
+
+                dinf = (DocumentSummaryInformation) PropertySetFactory.create(new DocumentInputStream(
+                    (DocumentEntry) root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
+                assertEquals(131333, dinf.getOSVersion());
+
+
+                // Add a test mini stream
+                testDir = root.createDirectory("Testing 123");
+                testDir.createDirectory("Testing 456");
+                testDir.createDirectory("Testing 789");
+                byte[] mini = new byte[]{42, 0, 1, 2, 3, 4, 42};
+                testDir.createDocument("Mini", new ByteArrayInputStream(mini));
+
+
+                // Write out, re-load
+                try (POIFSFileSystem fs3 = writeOutAndReadBack(fs2)) {
+
+                    root = fs3.getRoot();
+                    testDir = (DirectoryEntry) root.getEntry("Testing 123");
+                    assertEquals(6, root.getEntryCount());
+                    assertThat(root.getEntryNames(), hasItem("Thumbnail"));
+                    assertThat(root.getEntryNames(), hasItem("Image"));
+                    assertThat(root.getEntryNames(), hasItem("Tags"));
+                    assertThat(root.getEntryNames(), hasItem("Testing 123"));
+                    assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
+                    assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
+
+
+                    // Check old and new are there
+                    sinf = (SummaryInformation) PropertySetFactory.create(new DocumentInputStream(
+                        (DocumentEntry) root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
+                    assertEquals(131333, sinf.getOSVersion());
+
+                    dinf = (DocumentSummaryInformation) PropertySetFactory.create(new DocumentInputStream(
+                        (DocumentEntry) root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
+                    assertEquals(131333, dinf.getOSVersion());
+
+                    assertContentsMatches(mini, (DocumentEntry) testDir.getEntry("Mini"));
+
+
+                    // Write out and read once more, just to be sure
+                    try (POIFSFileSystem fs4 = writeOutAndReadBack(fs3)) {
+
+                        root = fs4.getRoot();
+                        testDir = (DirectoryEntry) root.getEntry("Testing 123");
+                        assertEquals(6, root.getEntryCount());
+                        assertThat(root.getEntryNames(), hasItem("Thumbnail"));
+                        assertThat(root.getEntryNames(), hasItem("Image"));
+                        assertThat(root.getEntryNames(), hasItem("Tags"));
+                        assertThat(root.getEntryNames(), hasItem("Testing 123"));
+                        assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
+                        assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
+
+                        sinf = (SummaryInformation) PropertySetFactory.create(new DocumentInputStream(
+                            (DocumentEntry) root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME)));
+                        assertEquals(131333, sinf.getOSVersion());
+
+                        dinf = (DocumentSummaryInformation) PropertySetFactory.create(new DocumentInputStream(
+                            (DocumentEntry) root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME)));
+                        assertEquals(131333, dinf.getOSVersion());
+
+                        assertContentsMatches(mini, (DocumentEntry) testDir.getEntry("Mini"));
+
+
+                        // Add a full stream, delete a full stream
+                        byte[] main4096 = new byte[4096];
+                        main4096[0] = -10;
+                        main4096[4095] = -11;
+                        testDir.createDocument("Normal4096", new ByteArrayInputStream(main4096));
+
+                        root.getEntry("Tags").delete();
+
+
+                        // Write out, re-load
+                        try (POIFSFileSystem fs5 = writeOutAndReadBack(fs4)) {
+
+                            // Check it's all there
+                            root = fs5.getRoot();
+                            testDir = (DirectoryEntry) root.getEntry("Testing 123");
+                            assertEquals(5, root.getEntryCount());
+                            assertThat(root.getEntryNames(), hasItem("Thumbnail"));
+                            assertThat(root.getEntryNames(), hasItem("Image"));
+                            assertThat(root.getEntryNames(), hasItem("Testing 123"));
+                            assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
+                            assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
+
+

[... 1634 lines stripped ...]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org