me.lightspeed7.mongofs.gridfs.GridFSInputFile Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mongoFS Show documentation
Show all versions of mongoFS Show documentation
An extension to the MongoDB Java Driver library that goes beyond what the GridFS feature supports.
Compressed file storage, zip files, temporary files
/*
* Copyright (c) 2008-2014 MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package me.lightspeed7.mongofs.gridfs;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import me.lightspeed7.mongofs.BufferedChunksOutputStream;
import me.lightspeed7.mongofs.FileChunksOutputStreamSink;
import me.lightspeed7.mongofs.InputFile;
import me.lightspeed7.mongofs.MongoFileConstants;
import me.lightspeed7.mongofs.util.BytesCopier;
import org.bson.types.ObjectId;
import org.mongodb.Document;
import org.mongodb.MongoCollection;
import com.mongodb.DBCollection;
import com.mongodb.MongoException;
/**
* This class represents a GridFS file to be written to the database Operations include: - writing data obtained from an InputStream -
* getting an OutputStream to stream the data out
*
* @author David Buschman
* @author Eliot Horowitz and Guy K. Kloss
*/
public class GridFSInputFile extends GridFSFile implements InputFile {
private final InputStream inputStream;
private final boolean closeStreamOnPersist;
private boolean savedChunks = false;
private OutputStream outputStream = null;
/**
* Default constructor setting the GridFS file name and providing an input stream containing data to be written to the file.
*
* @param fs
* The GridFS connection handle.
* @param in
* Stream used for reading data from.
* @param filename
* Name of the file to be created.
* @param closeStreamOnPersist
* indicate the passed in input stream should be closed once the data chunk persisted
*/
protected GridFSInputFile(final GridFS fs, final InputStream in, final String filename, final boolean closeStreamOnPersist) {
this.fs = fs;
this.inputStream = in;
this.filename = filename;
this.closeStreamOnPersist = closeStreamOnPersist;
this.id = new ObjectId();
this.chunkSize = GridFS.DEFAULT_CHUNKSIZE;
this.uploadDate = new Date();
}
private OutputStream generateOutputStream(final DBCollection collection) {
GridFSInputFileAdapter adapter = new GridFSInputFileAdapter(this);
FileChunksOutputStreamSink streamSink = new FileChunksOutputStreamSink(new MongoCollection(collection), this.id, adapter,
null);
BufferedChunksOutputStream stream = new BufferedChunksOutputStream(streamSink, this.chunkSize);
return stream;
}
/**
* Default constructor setting the GridFS file name and providing an input stream containing data to be written to the file.
*
* @param fs
* The GridFS connection handle.
* @param in
* Stream used for reading data from.
* @param filename
* Name of the file to be created.
*/
protected GridFSInputFile(final GridFS fs, final InputStream in, final String filename) {
this(fs, in, filename, false);
}
/**
* Constructor that only provides a file name, but does not rely on the presence of an {@link java.io.InputStream}. An
* {@link java.io.OutputStream} can later be obtained for writing using the {@link #getOutputStream()} method.
*
* @param fs
* The GridFS connection handle.
* @param filename
* Name of the file to be created.
*/
protected GridFSInputFile(final GridFS fs, final String filename) {
this(fs, null, filename);
}
/**
* Minimal constructor that does not rely on the presence of an {@link java.io.InputStream}. An {@link java.io.OutputStream} can later
* be obtained for writing using the {@link #getOutputStream()} method.
*
* @param fs
* The GridFS connection handle.
*/
protected GridFSInputFile(final GridFS fs) {
this(fs, null, null);
}
public void setId(final Object id) {
this.id = id;
}
/**
* Sets the file name on the GridFS entry.
*
* @param filename
* File name.
*/
public void setFilename(final String filename) {
this.filename = filename;
}
/**
* Sets the content type (MIME type) on the GridFS entry.
*
* @param contentType
* Content type.
*/
public void setContentType(final String contentType) {
this.contentType = contentType;
}
/**
* Set the chunk size. This must be called before saving any data.
*
* @param chunkSize
* The size in bytes.
*/
public void setChunkSize(final int chunkSize) {
if (outputStream != null || savedChunks) {
return;
}
this.chunkSize = chunkSize;
}
/**
* calls save with the existing chunk size.
*
* @throws MongoException
*/
@Override
public void save() {
save(chunkSize);
}
/**
* Internal use only!!
*/
final void superSave() {
super.save();
}
/**
* This method first calls saveChunks(long) if the file data has not been saved yet. Then it persists the file entry to GridFS.
*
* @param chunkSize
* Size of chunks for file in bytes.
* @throws MongoException
*/
public void save(final int chunkSize) {
if (outputStream != null) {
throw new MongoException("cannot mix OutputStream and regular save()");
}
// note that chunkSize only changes chunkSize in case we actually save chunks
// otherwise there is a risk file and chunks are not compatible
if (!savedChunks) {
try {
saveChunks(chunkSize);
} catch (IOException ioe) {
throw new MongoException("couldn't save chunks", ioe);
}
}
super.save();
}
/**
* Saves all data into chunks from configured {@link java.io.InputStream} input stream to GridFS.
*
* @return Number of the next chunk.
* @throws IOException
* on problems reading the new entry's {@link java.io.InputStream}.
* @throws MongoException
*/
public int saveChunks() throws IOException {
return saveChunks(chunkSize);
}
/**
* Saves all data into chunks from configured {@link java.io.InputStream} input stream to GridFS. A non-default chunk size can be
* specified. This method does NOT save the file object itself, one must call save() to do so.
*
* @param chunkSize
* Size of chunks for file in bytes.
* @return Number of the next chunk.
* @throws IOException
* on problems reading the new entry's {@link java.io.InputStream}.
* @throws MongoException
*/
public int saveChunks(final int chunkSize) throws IOException {
if (outputStream != null) {
throw new MongoException("Cannot mix OutputStream and regular save()");
}
if (savedChunks) {
throw new MongoException("Chunks already saved!");
}
if (chunkSize <= 0) {
throw new MongoException("chunkSize must be greater than zero");
}
if (this.chunkSize != chunkSize) {
this.chunkSize = chunkSize;
}
// new stuff
this.outputStream = generateOutputStream(fs.getChunksCollection());
try {
new BytesCopier(inputStream, this.outputStream, this.closeStreamOnPersist).transfer(false);
} finally {
this.outputStream.close();
}
// only write data, do not write file, in case one wants to change metadata
return (int) this.getAsLong(MongoFileConstants.chunkCount.name());
}
public OutputStream getOutputStream() {
if (outputStream == null) {
outputStream = generateOutputStream(fs.getChunksCollection());
}
return outputStream;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy