largeobject.java

来自「PostgreSQL7.4.6 for Linux」· Java 代码 · 共 329 行

JAVA
329
字号
/*------------------------------------------------------------------------- * * LargeObject.java *     This class implements the large object interface to org.postgresql. * * Copyright (c) 2003, PostgreSQL Global Development Group * * IDENTIFICATION *	  $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/largeobject/Attic/LargeObject.java,v 1.10 2003/03/07 18:39:45 barry Exp $ * *------------------------------------------------------------------------- */package org.postgresql.largeobject;import java.io.InputStream;import java.io.IOException;import java.io.OutputStream;import java.sql.SQLException;import org.postgresql.fastpath.Fastpath;import org.postgresql.fastpath.FastpathArg;/* * This class provides the basic methods required to run the interface, plus * a pair of methods that provide InputStream and OutputStream classes * for this object. * * <p>Normally, client code would use the getAsciiStream, getBinaryStream, * or getUnicodeStream methods in ResultSet, or setAsciiStream, * setBinaryStream, or setUnicodeStream methods in PreparedStatement to * access Large Objects. * * <p>However, sometimes lower level access to Large Objects are required, * that are not supported by the JDBC specification. * * <p>Refer to org.postgresql.largeobject.LargeObjectManager on how to gain access * to a Large Object, or how to create one. * * @see org.postgresql.largeobject.LargeObjectManager * @see java.sql.ResultSet#getAsciiStream * @see java.sql.ResultSet#getBinaryStream * @see java.sql.ResultSet#getUnicodeStream * @see java.sql.PreparedStatement#setAsciiStream * @see java.sql.PreparedStatement#setBinaryStream * @see java.sql.PreparedStatement#setUnicodeStream * */public class LargeObject{	/*	 * Indicates a seek from the begining of a file	 */	public static final int SEEK_SET = 0;	/*	 * Indicates a seek from the current position	 */	public static final int SEEK_CUR = 1;	/*	 * Indicates a seek from the end of a file	 */	public static final int SEEK_END = 2;	private Fastpath	fp; // Fastpath API to use	private int oid;	// OID of this object	private int fd; // the descriptor of the open large object	private BlobOutputStream os;  // The current output stream	private boolean closed = false; // true when we are closed	/*	 * This opens a large object.	 *	 * <p>If the object does not exist, then an SQLException is thrown.	 *	 * @param fp FastPath API for the connection to use	 * @param oid of the Large Object to open	 * @param mode Mode of opening the large object	 * (defined in LargeObjectManager)	 * @exception SQLException if a database-access error occurs.	 * @see org.postgresql.largeobject.LargeObjectManager	 */	protected LargeObject(Fastpath fp, int oid, int mode) throws SQLException	{		this.fp = fp;		this.oid = oid;		FastpathArg args[] = new FastpathArg[2];		args[0] = new FastpathArg(oid);		args[1] = new FastpathArg(mode);		this.fd = fp.getInteger("lo_open", args);	}	/* Release large object resources during garbage cleanup */	protected void finalize() throws SQLException	{		//This code used to call close() however that was problematic		//because the scope of the fd is a transaction, thus if commit		//or rollback was called before garbage collection ran then		//the call to close would error out with an invalid large object		//handle.  So this method now does nothing and lets the server		//handle cleanup when it ends the transaction.	}	/*	 * @return the OID of this LargeObject	 */	public int getOID()	{		return oid;	}	/*	 * This method closes the object. You must not call methods in this	 * object after this is called.	 * @exception SQLException if a database-access error occurs.	 */	public void close() throws SQLException	{		if (!closed)		{			// flush any open output streams			if (os != null)			{				try				{					// we can't call os.close() otherwise we go into an infinite loop!					os.flush();				}				catch (IOException ioe)				{					throw new SQLException(ioe.getMessage());				}				finally				{					os = null;				}			}			// finally close			FastpathArg args[] = new FastpathArg[1];			args[0] = new FastpathArg(fd);			fp.fastpath("lo_close", false, args); // true here as we dont care!!			closed = true;		}	}	/*	 * Reads some data from the object, and return as a byte[] array	 *	 * @param len number of bytes to read	 * @return byte[] array containing data read	 * @exception SQLException if a database-access error occurs.	 */	public byte[] read(int len) throws SQLException	{		// This is the original method, where the entire block (len bytes)		// is retrieved in one go.		FastpathArg args[] = new FastpathArg[2];		args[0] = new FastpathArg(fd);		args[1] = new FastpathArg(len);		return fp.getData("loread", args);		// This version allows us to break this down into 4k blocks		//if (len<=4048) {		//// handle as before, return the whole block in one go		//FastpathArg args[] = new FastpathArg[2];		//args[0] = new FastpathArg(fd);		//args[1] = new FastpathArg(len);		//return fp.getData("loread",args);		//} else {		//// return in 4k blocks		//byte[] buf=new byte[len];		//int off=0;		//while (len>0) {		//int bs=4048;		//len-=bs;		//if (len<0) {		//bs+=len;		//len=0;		//}		//read(buf,off,bs);		//off+=bs;		//}		//return buf;		//}	}	/*	 * Reads some data from the object into an existing array	 *	 * @param buf destination array	 * @param off offset within array	 * @param len number of bytes to read	 * @return the number of bytes actually read	 * @exception SQLException if a database-access error occurs.	 */	public int read(byte buf[], int off, int len) throws SQLException	{		byte b[] = read(len);		if (b.length < len)			len = b.length;		System.arraycopy(b, 0, buf, off, len);		return len;	}	/*	 * Writes an array to the object	 *	 * @param buf array to write	 * @exception SQLException if a database-access error occurs.	 */	public void write(byte buf[]) throws SQLException	{		FastpathArg args[] = new FastpathArg[2];		args[0] = new FastpathArg(fd);		args[1] = new FastpathArg(buf);		fp.fastpath("lowrite", false, args);	}	/*	 * Writes some data from an array to the object	 *	 * @param buf destination array	 * @param off offset within array	 * @param len number of bytes to write	 * @exception SQLException if a database-access error occurs.	 */	public void write(byte buf[], int off, int len) throws SQLException	{		byte data[] = new byte[len];		System.arraycopy(buf, off, data, 0, len);		write(data);	}	/*	 * Sets the current position within the object.	 *	 * <p>This is similar to the fseek() call in the standard C library. It	 * allows you to have random access to the large object.	 *	 * @param pos position within object	 * @param ref Either SEEK_SET, SEEK_CUR or SEEK_END	 * @exception SQLException if a database-access error occurs.	 */	public void seek(int pos, int ref) throws SQLException	{		FastpathArg args[] = new FastpathArg[3];		args[0] = new FastpathArg(fd);		args[1] = new FastpathArg(pos);		args[2] = new FastpathArg(ref);		fp.fastpath("lo_lseek", false, args);	}	/*	 * Sets the current position within the object.	 *	 * <p>This is similar to the fseek() call in the standard C library. It	 * allows you to have random access to the large object.	 *	 * @param pos position within object from begining	 * @exception SQLException if a database-access error occurs.	 */	public void seek(int pos) throws SQLException	{		seek(pos, SEEK_SET);	}	/*	 * @return the current position within the object	 * @exception SQLException if a database-access error occurs.	 */	public int tell() throws SQLException	{		FastpathArg args[] = new FastpathArg[1];		args[0] = new FastpathArg(fd);		return fp.getInteger("lo_tell", args);	}	/*	 * This method is inefficient, as the only way to find out the size of	 * the object is to seek to the end, record the current position, then	 * return to the original position.	 *	 * <p>A better method will be found in the future.	 *	 * @return the size of the large object	 * @exception SQLException if a database-access error occurs.	 */	public int size() throws SQLException	{		int cp = tell();		seek(0, SEEK_END);		int sz = tell();		seek(cp, SEEK_SET);		return sz;	}	/*	 * Returns an InputStream from this object.	 *	 * <p>This InputStream can then be used in any method that requires an	 * InputStream.	 *	 * @exception SQLException if a database-access error occurs.	 */	public InputStream getInputStream() throws SQLException	{		return new BlobInputStream(this, 4096);	}	/*	 * Returns an OutputStream to this object	 *	 * <p>This OutputStream can then be used in any method that requires an	 * OutputStream.	 *	 * @exception SQLException if a database-access error occurs.	 */	public OutputStream getOutputStream() throws SQLException	{		if (os == null)			os = new BlobOutputStream(this, 4096);		return os;	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?