KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > fortress > tools > ChangedFileOutputStream


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14  * implied.
15  *
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19
20 package org.apache.avalon.fortress.tools;
21
22 import java.io.ByteArrayOutputStream JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.OutputStream JavaDoc;
28
29 /**
30  * OutputStream which will only update an existing file if its contents
31  * actually change. Needed to keep Ant from rebuilding jars even when
32  * nothing has changed.
33  *
34  * @author <a HREF="mailto:dev@avalon.apache.org">The Avalon Team</a>
35  * @version CVS $Revision: 1.1 $ $Date: 2004/04/02 08:29:44 $
36  */

37 public final class ChangedFileOutputStream
38     extends OutputStream JavaDoc
39 {
40     /** The file to write to. */
41     private File JavaDoc m_file;
42     
43     /** The output stream used to buffer data being writen. */
44     private ByteArrayOutputStream JavaDoc m_bos;
45     
46     /*---------------------------------------------------------------
47      * Constructor
48      *-------------------------------------------------------------*/

49     /**
50      * Creates a new ChangedFileOutputStream.
51      *
52      * @param file The file to write to.
53      */

54     public ChangedFileOutputStream( File JavaDoc file )
55     {
56         m_file = file;
57         m_bos = new ByteArrayOutputStream JavaDoc();
58     }
59     
60     /*---------------------------------------------------------------
61      * OutputStream Methods
62      *-------------------------------------------------------------*/

63     /**
64      * Writes the specified byte to this output stream.
65      *
66      * @param b Byte to write.
67      *
68      * @throws IOException If an I/O error occurs.
69      */

70     public void write( int b )
71         throws IOException JavaDoc
72     {
73         m_bos.write( b );
74     }
75     
76     /**
77      * Close the stream.
78      *
79      * @throws IOException If an I/O error occurs.
80      */

81     public void close()
82         throws IOException JavaDoc
83     {
84         byte[] newContent = m_bos.toByteArray();
85         m_bos.close();
86         
87         boolean changed;
88         if ( m_file.exists() )
89         {
90             byte[] oldContent = readBytes( m_file );
91             
92             // Compare the old and new bytes.
93
if ( newContent.length != oldContent.length )
94             {
95                 changed = true;
96             }
97             else
98             {
99                 changed = false;
100                 for ( int i = 0; i < newContent.length; i++ )
101                 {
102                     if ( newContent[i] != oldContent[i] )
103                     {
104                         changed = true;
105                         break;
106                     }
107                 }
108             }
109         }
110         else
111         {
112             // File does not exist.
113
changed = true;
114         }
115         
116         if ( changed )
117         {
118             writeBytes( m_file, newContent );
119         }
120     }
121     
122     /*---------------------------------------------------------------
123      * Methods
124      *-------------------------------------------------------------*/

125     /**
126      * Reads the full contents of a file into a byte array. The file contents
127      * are treated as binary data.
128      *
129      * @param file File to read.
130      *
131      * @return The contents of the file as a byte array.
132      *
133      * @throws IOException If the file could not be read for any reason.
134      */

135     private byte[] readBytes( File JavaDoc file )
136         throws IOException JavaDoc
137     {
138         byte[] bytes = new byte[(int)file.length()];
139         
140         FileInputStream JavaDoc is = new FileInputStream JavaDoc( file );
141         try
142         {
143             // Make sure all bytes are read in.
144
int pos = 0;
145             int read;
146             while ( ( pos < bytes.length ) &&
147                 ( ( read = is.read( bytes, pos, bytes.length - pos ) ) >= 0 ) )
148             {
149                 pos += read;
150             }
151         }
152         finally
153         {
154             is.close();
155         }
156         
157         return bytes;
158     }
159     
160     /**
161      * Reads the full contents of a byte array out to a file.
162      *
163      * @param file File to write to.
164      * @param bytes The binary data to write.
165      *
166      * @throws IOException If the file could not be written to for any reason.
167      */

168     private void writeBytes( File JavaDoc file, byte[] bytes )
169         throws IOException JavaDoc
170     {
171         FileOutputStream JavaDoc os = new FileOutputStream JavaDoc( file );
172         try
173         {
174             os.write( bytes, 0, bytes.length );
175         }
176         finally
177         {
178             os.close();
179         }
180     }
181 }
182
Popular Tags