KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > archive > io > ObjectPlusFilesOutputStream


1 /* ObjectPlusFilesOutputStream
2 *
3 * $Id: ObjectPlusFilesOutputStream.java,v 1.2.12.1 2007/01/13 01:31:32 stack-sf Exp $
4 *
5 * Created on Apr 28, 2004
6 *
7 * Copyright (C) 2004 Internet Archive.
8 *
9 * This file is part of the Heritrix web crawler (crawler.archive.org).
10 *
11 * Heritrix is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * any later version.
15 *
16 * Heritrix is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser Public License
22 * along with Heritrix; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */

25 package org.archive.io;
26
27 import java.io.File JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.ObjectOutputStream JavaDoc;
30 import java.io.OutputStream JavaDoc;
31 import java.util.LinkedList JavaDoc;
32
33 import org.archive.util.FileUtils;
34
35
36 /**
37  * Enhanced ObjectOutputStream which maintains (a stack of) auxiliary
38  * directories and offers convenience methods for serialized objects
39  * to save their related disk files alongside their serialized version.
40  *
41  * @author gojomo
42  */

43 public class ObjectPlusFilesOutputStream extends ObjectOutputStream JavaDoc {
44     LinkedList JavaDoc<File JavaDoc> auxiliaryDirectoryStack = new LinkedList JavaDoc<File JavaDoc>();
45
46     /**
47      * Constructor
48      *
49      * @param out
50      * @param topDirectory
51      * @throws java.io.IOException
52      */

53     public ObjectPlusFilesOutputStream(OutputStream JavaDoc out, File JavaDoc topDirectory) throws IOException JavaDoc {
54         super(out);
55         auxiliaryDirectoryStack.addFirst(topDirectory);
56     }
57
58     /**
59      * Add another subdirectory for any file-capture needs during the
60      * current serialization.
61      *
62      * @param dir
63      */

64     public void pushAuxiliaryDirectory(String JavaDoc dir) {
65         auxiliaryDirectoryStack.addFirst(new File JavaDoc(getAuxiliaryDirectory(),dir));
66     }
67
68     /**
69      * Remove the top subdirectory.
70      *
71      */

72     public void popAuxiliaryDirectory() {
73         auxiliaryDirectoryStack.removeFirst();
74     }
75
76     /**
77      * Return the current auxiliary directory for storing
78      * files associated with serialized objects.
79      *
80      * @return Auxillary directory.
81      */

82     public File JavaDoc getAuxiliaryDirectory() {
83         return (File JavaDoc)auxiliaryDirectoryStack.getFirst();
84     }
85
86     /**
87      * Store a snapshot of an object's supporting file to the
88      * current auxiliary directory. Should only be used for
89      * files which are strictly appended-to, because it tries
90      * to use a "hard link" where possible (meaning that
91      * future edits to the original file's contents will
92      * also affect the snapshot).
93      *
94      * Remembers current file extent to allow a future restore
95      * to ignore subsequent appended data.
96      *
97      * @param file
98      * @throws IOException
99      */

100     public void snapshotAppendOnlyFile(File JavaDoc file) throws IOException JavaDoc {
101         // write filename
102
String JavaDoc name = file.getName();
103         writeUTF(name);
104         // write current file length
105
writeLong(file.length());
106         File JavaDoc auxDir = getAuxiliaryDirectory();
107         if(!auxDir.exists()) {
108             auxDir.mkdirs();
109         }
110         File JavaDoc destination = new File JavaDoc(auxDir,name);
111         hardlinkOrCopy(file, destination);
112     }
113
114     /**
115      * Create a backup of this given file, first by trying a "hard
116      * link", then by using a copy if hard linking is unavailable
117      * (either because it is unsupported or the origin and checkpoint
118      * directories are on different volumes).
119      *
120      * @param file
121      * @param destination
122      * @throws IOException
123      */

124     private void hardlinkOrCopy(File JavaDoc file, File JavaDoc destination) throws IOException JavaDoc {
125         // For Linux/UNIX, try a hard link first.
126
Process JavaDoc link = Runtime.getRuntime().exec("ln "+file.getAbsolutePath()+" "+destination.getAbsolutePath());
127         // TODO NTFS also supports hard links; add appropriate try
128
try {
129             link.waitFor();
130         } catch (InterruptedException JavaDoc e) {
131             // TODO Auto-generated catch block
132
e.printStackTrace();
133         }
134         if(link.exitValue()!=0) {
135             // hard link failed
136
FileUtils.copyFile(file,destination);
137         }
138     }
139
140 }
141
Popular Tags