Skip to content

Package: TempFile

TempFile

nameinstructionbranchcomplexitylinemethod
TempFile(File)
M: 19 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
close()
M: 10 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
finalize()
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
getAppendStream()
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
length()
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
newStream(long, long)
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.eclipse.angus.mail.mbox;
18:
19: import jakarta.mail.util.SharedFileInputStream;
20:
21: import java.io.File;
22: import java.io.IOException;
23: import java.io.InputStream;
24: import java.io.OutputStream;
25: import java.io.RandomAccessFile;
26:
27: /**
28: * A temporary file used to cache messages.
29: */
30: class TempFile {
31:
32: private File file; // the temp file name
33: private WritableSharedFile sf;
34:
35: /**
36: * Create a temp file in the specified directory (if not null).
37: * The file will be deleted when the JVM exits.
38: */
39: public TempFile(File dir) throws IOException {
40: file = File.createTempFile("mbox.", ".mbox", dir);
41: // XXX - need JDK 6 to set permissions on the file to owner-only
42: file.deleteOnExit();
43: sf = new WritableSharedFile(file);
44: }
45:
46: /**
47: * Return a stream for appending to the temp file.
48: */
49: public AppendStream getAppendStream() throws IOException {
50: return sf.getAppendStream();
51: }
52:
53: /**
54: * Return a stream for reading from part of the file.
55: */
56: public InputStream newStream(long start, long end) {
57: return sf.newStream(start, end);
58: }
59:
60: public long length() {
61: return file.length();
62: }
63:
64: /**
65: * Close and remove this temp file.
66: */
67: public void close() {
68: try {
69: sf.close();
70: } catch (IOException ex) {
71: // ignore it
72: }
73: file.delete();
74: }
75:
76: protected void finalize() throws Throwable {
77: try {
78: close();
79: } finally {
80: super.finalize();
81: }
82: }
83: }
84:
85: /**
86: * A subclass of SharedFileInputStream that also allows writing.
87: */
88: class WritableSharedFile extends SharedFileInputStream {
89: private RandomAccessFile raf;
90: private AppendStream af;
91:
92: public WritableSharedFile(File file) throws IOException {
93: super(file);
94: try {
95: raf = new RandomAccessFile(file, "rw");
96: } catch (IOException ex) {
97: // if anything goes wrong opening the writable file,
98: // close the readable file too
99: super.close();
100: }
101: }
102:
103: /**
104: * Return the writable version of this file.
105: */
106: public RandomAccessFile getWritableFile() {
107: return raf;
108: }
109:
110: /**
111: * Close the readable and writable files.
112: */
113: public void close() throws IOException {
114: try {
115: super.close();
116: } finally {
117: raf.close();
118: }
119: }
120:
121: /**
122: * Update the size of the readable file after writing
123: * to the file. Updates the length to be the current
124: * size of the file.
125: */
126: synchronized long updateLength() throws IOException {
127: datalen = in.length();
128: af = null;
129: return datalen;
130: }
131:
132: /**
133: * Return a new AppendStream, but only if one isn't in active use.
134: */
135: public synchronized AppendStream getAppendStream() throws IOException {
136: if (af != null)
137: throw new IOException(
138: "file cache only supports single threaded access");
139: af = new AppendStream(this);
140: return af;
141: }
142: }
143:
144: /**
145: * A stream for writing to the temp file, and when done
146: * can return a stream for reading the data just written.
147: * NOTE: We assume that only one thread is writing to the
148: * file at a time.
149: */
150: class AppendStream extends OutputStream {
151: private final WritableSharedFile tf;
152: private RandomAccessFile raf;
153: private final long start;
154: private long end;
155:
156: public AppendStream(WritableSharedFile tf) throws IOException {
157: this.tf = tf;
158: raf = tf.getWritableFile();
159: start = raf.length();
160: raf.seek(start);
161: }
162:
163: public void write(int b) throws IOException {
164: raf.write(b);
165: }
166:
167: public void write(byte[] b) throws IOException {
168: raf.write(b);
169: }
170:
171: public void write(byte[] b, int off, int len) throws IOException {
172: raf.write(b, off, len);
173: }
174:
175: public synchronized void close() throws IOException {
176: end = tf.updateLength();
177: raf = null; // no more writing allowed
178: }
179:
180: public synchronized InputStream getInputStream() throws IOException {
181: return tf.newStream(start, end);
182: }
183: }