Package com.enterprisedt.net.ftp

Source Code of com.enterprisedt.net.ftp.FTPOutputStream

/**
*
*  Copyright (C) 2007 Enterprise Distributed Technologies Ltd
*
*  www.enterprisedt.com
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*  Bug fixes, suggestions and comments should be should posted on
*  http://www.enterprisedt.com/forums/index.php
*
*  Change Log:
*
*    $Log: FTPOutputStream.java,v $
*    Revision 1.2  2009-01-15 03:37:30  bruceb
*    fix bug re this.remoteFile
*
*    Revision 1.1  2007-12-18 07:52:06  bruceb
*    2.0 changes
*
*
*/
package com.enterprisedt.net.ftp;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import com.enterprisedt.util.debug.Logger;

/**
*  Represents an output stream that writes to an FTP server, permitting
*  the user to upload a file by writing to the stream. It can only be used
*  for one upload, i.e. after the stream is closed it cannot be reopened.
*
@author      Bruce Blackshaw
@version     $Revision: 1.2 $
*/
public class FTPOutputStream extends FileTransferOutputStream {
   
    private static Logger log = Logger.getLogger("FTPOutputStream");
   
    /**
     * Interval that we notify the monitor of progress
     */
    private long monitorInterval;
     
    /**
     * The client being used to perform the transfer
     */
    private FTPClient client;
   
    /**
     * The output stream to the FTP server
     */
    private BufferedOutputStream out;
   
    /**
     * Number of bytes downloaded
     */
    private long size = 0;
   
    /**
     * Is this an ASCII transfer or not?
     */
    private boolean isASCII = false;
   
    /**
     * Count of byte since last the progress monitor was notified.
     */
    private long monitorCount = 0;

    /**
     * Progress monitor reference
     */
    private FTPProgressMonitor monitor;
   
    /**
     * Progress monitor reference
     */
    private FTPProgressMonitorEx monitorEx;
   
   
    /**
     * Previously read bytes that match the line terminator
     */
    private byte[] prevBuf = new byte[FTPClient.FTP_LINE_SEPARATOR.length];
   
    /**
     * Where we are up to in prevBuf re matches
     */
    private int matchpos = 0;
       
    /**
     * Constructor. A connected FTPClient instance must be supplied. This sets up the
     * download.
     *
     * @param client            connected FTPClient instance (or subclass)
     * @param remoteFile        name of remote file (if null, the server <b>may</b>
     *                           be able to generate a name
     * @throws IOException
     * @throws FTPException
     */
    public FTPOutputStream(FTPClient client, String remoteFile) throws IOException, FTPException {
        this(client, remoteFile, false);
    }


    /**
     * Constructor. A connected FTPClient instance must be supplied. This sets up the
     * download.
     *
     * @param client            connected FTPClient instance (or subclass)
     * @param remoteFile        name of remote file (if null, the server <b>may</b>
     *                           be able to generate a name
     * @param append            true if appending on the server
     * @throws IOException
     * @throws FTPException
     */
    public FTPOutputStream(FTPClient client, String remoteFile, boolean append) throws IOException, FTPException {
        this.client = client;
        this.remoteFile = remoteFile;
        try {
            this.remoteFile = client.initPut(remoteFile, append);

            // get an input stream to read data from ... AFTER we have
            // the ok to go ahead AND AFTER we've successfully opened a
            // stream for the local file
            out =
                new BufferedOutputStream(
                        new DataOutputStream(client.getOutputStream()), client.getTransferBufferSize()*2);

        }
        catch (IOException ex) {
            client.validateTransferOnError(ex);
            throw ex;
        }
       
        this.monitorInterval = client.getMonitorInterval();
        this.monitor = client.getProgressMonitor();
        this.isASCII = (client.getType().equals(FTPTransferType.ASCII));
    }
   
   
    /**
     * The output stream uses the progress monitor currently owned by the FTP client.
     * This method allows a different progress monitor to be passed in, or for the
     * monitor interval to be altered.
     *
     * @param monitor               progress monitor reference
     * @param monitorInterval      
     */
    public void setMonitor(FTPProgressMonitorEx monitor, long monitorInterval) {
        this.monitor = monitor;
        this.monitorEx = monitor;
        this.monitorInterval = monitorInterval;
    }
    /**
     * Writes <code>b.length</code> bytes from the specified byte array
     * to this output stream.
     *
     * @param      b   the data.
     * @exception  IOException  if an I/O error occurs.
     */
    public void write(int b) throws IOException {
        byte[] tmp = new byte[1];
        tmp[0] = (byte)b;
        write(tmp, 0, 1);
    }
   
   
    /**
     * Writes <code>len</code> bytes from the specified byte array
     * starting at offset <code>off</code> to this output stream.
     *
     * @param      b     the data.
     * @param      off   the start offset in the data.
     * @param      len   the number of bytes to write.
     * @exception  IOException  if an I/O error occurs.
     */
    public void write(byte b[], int off, int len) throws IOException {
        if (isASCII) {
            for (int i = off; i < off+len; i++) {
                // LF without preceding CR (i.e. Unix text file)
                if (b[i] == FTPClient.LINE_FEED && matchpos == 0) {
                    out.write(FTPClient.CARRIAGE_RETURN);
                    out.write(FTPClient.LINE_FEED);
                    size += 2;
                    monitorCount += 2;
                }
                else if (b[i] == FTPClient.FTP_LINE_SEPARATOR[matchpos]) {
                    prevBuf[matchpos] = b[i];
                    matchpos++;
                    if (matchpos == FTPClient.FTP_LINE_SEPARATOR.length) {
                        out.write(FTPClient.CARRIAGE_RETURN);
                        out.write(FTPClient.LINE_FEED);
                        size += 2;
                        monitorCount += 2;
                        matchpos = 0;
                    }
                }
                else { // no match current char
                    // this must be a matching \r if we matched first char
                    if (matchpos > 0) {
                        out.write(FTPClient.CARRIAGE_RETURN);
                        out.write(FTPClient.LINE_FEED);
                        size += 2;
                        monitorCount += 2;
                    }
                    out.write(b[i]);
                    size++;
                    monitorCount++;
                    matchpos = 0;
                }                             
            }
        }
        else { // binary
            out.write(b, off, len);
            size += len;
            monitorCount += len;
        }
                           
        if (monitor != null && monitorCount > monitorInterval) {
            monitor.bytesTransferred(size);
            monitorCount = 0
        }       
    }


   
    /**
     * Closes this output stream and releases any system resources associated
     * with the stream. This <b>must</b> be called before any other operations
     * are initiated on the FTPClient.
     *
     * @exception  IOException  if an I/O error occurs.
     */
    public void close() throws IOException {
       
        if (!closed) {
            closed = true;
           
            //  write out anything left at the end that has been saved
            if (isASCII && matchpos > 0) {
                out.write(prevBuf, 0, matchpos);
                size += matchpos;
                monitorCount += matchpos;
            }
           
            client.forceResumeOff();
   
            // close streams
            client.closeDataSocket(out);
           
            if (monitor != null)
                monitor.bytesTransferred(size)
   
            // log bytes transferred
            log.debug("Transferred " + size + " bytes from remote host");
           
            try {
                client.validateTransfer();
            }
            catch (FTPException ex) {
                throw new IOException(ex.getMessage());
            }
           
            if (monitorEx != null)
                monitorEx.transferComplete(TransferDirection.UPLOAD, remoteFile);
        }
    }
   
}
TOP

Related Classes of com.enterprisedt.net.ftp.FTPOutputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.