View | Details | Raw Unified | Return to bug 58480
Collapse All | Expand All

(-)poi/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java (-1 / +22 lines)
Lines 26-34 Link Here
26
import java.nio.channels.Channels;
26
import java.nio.channels.Channels;
27
import java.nio.channels.FileChannel;
27
import java.nio.channels.FileChannel;
28
import java.nio.channels.WritableByteChannel;
28
import java.nio.channels.WritableByteChannel;
29
import java.util.ArrayList;
30
import java.util.List;
29
31
30
import org.apache.poi.util.IOUtils;
32
import org.apache.poi.util.IOUtils;
31
33
34
import sun.nio.ch.DirectBuffer;
35
32
/**
36
/**
33
 * A POIFS {@link DataSource} backed by a File
37
 * A POIFS {@link DataSource} backed by a File
34
 */
38
 */
Lines 37-42 Link Here
37
   private boolean writable;
41
   private boolean writable;
38
   // remember file base, which needs to be closed too
42
   // remember file base, which needs to be closed too
39
   private RandomAccessFile srcFile;
43
   private RandomAccessFile srcFile;
44
   
45
   // Buffers which map to a file-porition are not closed automatically when the Channel is closed
46
   // therefore we keep the list of mapped buffers and 
47
   // See https://bz.apache.org/bugzilla/show_bug.cgi?id=58480, 
48
   // http://stackoverflow.com/questions/3602783/file-access-synchronized-on-java-object and
49
   // and http://bugs.java.com/view_bug.do?bug_id=4724038 for related discussions
50
   private List<DirectBuffer> buffersToClean = new ArrayList<DirectBuffer>();
40
51
41
   public FileBackedDataSource(File file) throws FileNotFoundException {
52
   public FileBackedDataSource(File file) throws FileNotFoundException {
42
       this(newSrcFile(file, "r"), true);
53
       this(newSrcFile(file, "r"), true);
Lines 91-96 Link Here
91
      // Ready it for reading
102
      // Ready it for reading
92
      dst.position(0);
103
      dst.position(0);
93
104
105
      // remember the buffer for cleanup if necessary
106
      if(dst instanceof DirectBuffer) {
107
          buffersToClean.add((DirectBuffer)dst);
108
      }
109
      
94
      // All done
110
      // All done
95
      return dst;
111
      return dst;
96
   }
112
   }
Lines 115-121 Link Here
115
131
116
   @Override
132
   @Override
117
   public void close() throws IOException {
133
   public void close() throws IOException {
118
      if (srcFile != null) {
134
       for(DirectBuffer buffer : buffersToClean) {
135
           buffer.cleaner().clean();
136
       }
137
       buffersToClean.clear();
138
139
       if (srcFile != null) {
119
          // see http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4796385
140
          // see http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4796385
120
          srcFile.close();
141
          srcFile.close();
121
      } else {
142
      } else {
(-)poi/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (-28 / +30 lines)
Lines 1372-1407 Link Here
1372
	public void write(OutputStream stream)
1372
	public void write(OutputStream stream)
1373
            throws IOException
1373
            throws IOException
1374
    {
1374
    {
1375
        byte[] bytes = getBytes();
1376
        NPOIFSFileSystem fs = new NPOIFSFileSystem();
1375
        NPOIFSFileSystem fs = new NPOIFSFileSystem();
1377
1376
        try {
1378
        // For tracking what we've written out, used if we're
1377
            // For tracking what we've written out, used if we're
1379
        //  going to be preserving nodes
1378
            //  going to be preserving nodes
1380
        List<String> excepts = new ArrayList<String>(1);
1379
            List<String> excepts = new ArrayList<String>(1);
1381
1380
    
1382
        // Write out the Workbook stream
1381
            // Write out the Workbook stream
1383
        fs.createDocument(new ByteArrayInputStream(bytes), "Workbook");
1382
            fs.createDocument(new ByteArrayInputStream(getBytes()), "Workbook");
1384
1383
    
1385
        // Write out our HPFS properties, if we have them
1384
            // Write out our HPFS properties, if we have them
1386
        writeProperties(fs, excepts);
1385
            writeProperties(fs, excepts);
1387
1386
    
1388
        if (preserveNodes) {
1387
            if (preserveNodes) {
1389
            // Don't write out the old Workbook, we'll be doing our new one
1388
                // Don't write out the old Workbook, we'll be doing our new one
1390
            // If the file had an "incorrect" name for the workbook stream,
1389
                // If the file had an "incorrect" name for the workbook stream,
1391
            // don't write the old one as we'll use the correct name shortly
1390
                // don't write the old one as we'll use the correct name shortly
1392
        	excepts.addAll(Arrays.asList(WORKBOOK_DIR_ENTRY_NAMES));
1391
            	excepts.addAll(Arrays.asList(WORKBOOK_DIR_ENTRY_NAMES));
1393
1392
    
1394
            // Copy over all the other nodes to our new poifs
1393
                // Copy over all the other nodes to our new poifs
1395
            EntryUtils.copyNodes(
1394
                EntryUtils.copyNodes(
1396
                    new FilteringDirectoryNode(this.directory, excepts)
1395
                        new FilteringDirectoryNode(this.directory, excepts)
1397
                    , new FilteringDirectoryNode(fs.getRoot(), excepts)
1396
                        , new FilteringDirectoryNode(fs.getRoot(), excepts)
1398
            );
1397
                );
1399
1398
    
1400
            // YK: preserve StorageClsid, it is important for embedded workbooks,
1399
                // YK: preserve StorageClsid, it is important for embedded workbooks,
1401
            // see Bugzilla 47920
1400
                // see Bugzilla 47920
1402
            fs.getRoot().setStorageClsid(this.directory.getStorageClsid());
1401
                fs.getRoot().setStorageClsid(this.directory.getStorageClsid());
1402
            }
1403
            fs.writeFilesystem(stream);
1404
        } finally {
1405
            fs.close();
1403
        }
1406
        }
1404
        fs.writeFilesystem(stream);
1405
    }
1407
    }
1406
1408
1407
    /**
1409
    /**

Return to bug 58480