001: /*
002: * StreamContent.java November 2002
003: *
004: * Copyright (C) 2002, Niall Gallagher <niallg@users.sf.net>
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General
016: * Public License along with this library; if not, write to the
017: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
018: * Boston, MA 02111-1307 USA
019: */
020:
021: package simple.http.serve;
022:
023: import java.io.OutputStream;
024: import java.io.InputStream;
025: import java.io.IOException;
026:
027: /**
028: * The <code>StreamContent</code> object wraps a file which is
029: * too large to be buffered fully. Buffering resources requires a
030: * large amount of memory, this <code>Content</code> implementation
031: * ensures that the entire file is not stored in memory.
032: * <p>
033: * This allocates a buffer two kilobytes in size which is used to
034: * transfer the contents of a <code>File</code> object to the
035: * issued <code>OutputStream</code>. The <code>getContentType</code>
036: * method returns the value of <code>Context.getContentType</code>.
037: *
038: * @author Niall Gallagher
039: */
040: final class StreamContent extends IndexedContent {
041:
042: /**
043: * Constructor for the <code>StreamContent</code> creates an
044: * instance of the <code>Content</code> for large files. This uses
045: * the <code>Context.doIndex</code> method to retrieve a the meta
046: * information of the <code>File</code> represented by this.
047: *
048: * @param context the <code>Context</code> used for indexing
049: * @param target this is the request URI that refers to the file
050: */
051: public StreamContent(Context context, String target) {
052: super (context, target);
053: }
054:
055: /**
056: * The <code>write</code> method writes the contents of the file
057: * to the issued output stream provided. This is done by acquiring
058: * an input stream for the file and transferring the contents of
059: * that stream in two kilobyte chunks to the given output stream.
060: *
061: * @param out the <code>OutputStream</code> to write the contents
062: *
063: * @exception IOException this is thrown if the issued stream has
064: * an I/O problem writing the contents
065: */
066: public void write(OutputStream out) throws IOException {
067: int size = getLength();
068:
069: if (size > 0) {
070: write(out, size);
071: }
072: }
073:
074: /**
075: * This <code>write</code> method writes a specific number of bytes
076: * from the contents of the file. This is simply used as a driver
077: * for piping the contents of the file to the provided stream. The
078: * number of bytes to be streamed must be greater than zero.
079: *
080: * @param out the <code>OutputStream</code> to write the contents
081: * @param size this is the number of bytes to read from the file
082: *
083: * @exception IOException this is thrown if the issued stream has
084: * an I/O problem writing the contents
085: */
086: private void write(OutputStream out, int size) throws IOException {
087: InputStream in = getInputStream();
088:
089: if (size > 0) {
090: write(out, in, size);
091: }
092: in.close();
093: }
094:
095: /**
096: * The <code>write</code> method acts as a pipe, in that it will
097: * transfer the contents of the provided input stream to the ouput
098: * stream. This will transfer the contents of the file in chunks
099: * of two kilobytes in size. The provided input stream is closed
100: * once the contents of the file have been transferred.
101: *
102: * @param out the <code>OutputStream</code> to write the contents
103: * @param in this is the <code>InputStream</code> to read from
104: *
105: * @exception IOException this is thrown if the issued stream has
106: * an I/O problem writing the contents
107: */
108: private void write(OutputStream out, InputStream in, int size)
109: throws IOException {
110: byte[] swap = new byte[2048];
111:
112: while (true) {
113: int len = in.read(swap);
114:
115: if (len < 0) {
116: break;
117: }
118: out.write(swap, 0, len);
119: }
120: }
121: }
|