📄 filetransfer.java
字号:
/*
File Transfer classes to copy, and download files.
copyright (c) 1999-2008 Roedy Green, Canadian Mind Products
May be copied and used freely for any purpose but military.
Roedy Green
Canadian Mind Products
#101 - 2536 Wark Street
Victoria, BC
Canada V8T 4G8
tel: (250) 361-9093
roedy g at mindprod dotcom
http://mindprod.com
version history
1.2 1999-10-26 split off from FileTransfer
1.6 2002-04-22 conforming package name.
1.9 2006-02-05 reformat with IntelliJ, add Javadoc
2.0 2007-05-17 add pad and icon
2.1 2007-08-04 convert to JDK 1.5,
add timeout support
add sleep to avoid hogging CPU on stall
add support for preferred MIME types on download.
2.2 2007-08-24 use http Read methods.
2.3 2007-09-26 add timeout.
2.4 2008-07-05 add append method.
2.5 2008-08-10 add setReadTimeout and setConnectTimeout methods.
*/
package com.mindprod.filetransfer;
import com.mindprod.http.Read;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
/**
* copy or download a file. To read or write from the client's local hard disk, you will need a signed Applet and
* security clearance. see Signed Applet in the Java glossary. To read a files from the server, the file must be given
* public read access, usually the default. To write a file to the server, you server will have to support CGI-PUT with
* public access. This is unusual to find. Normally you upload files with FTP. See FTP in the Java glossary.
* See also the simpler hunkio package.
*
* @author Roedy Green, Canadian Mind Products
* @version 2.5 2008-08-10 add setReadTimeout and setConnectTimeout methods.
*/
public class FileTransfer extends MiniFileTransfer
{
// ------------------------------ FIELDS ------------------------------
/**
* undisplayed copyright notice
*/
@SuppressWarnings( { "UnusedDeclaration" } )
public static final String EMBEDDED_COPYRIGHT =
"copyright (c) 1999-2008 Roedy Green, Canadian Mind Products, http://mindprod.com";
@SuppressWarnings( { "UnusedDeclaration" } )
private static final String RELEASE_DATE = "2008-08-10";
/**
* embedded version string.
*/
@SuppressWarnings( { "UnusedDeclaration" } )
public static final String VERSION_STRING = "2.5";
// -------------------------- PUBLIC INSTANCE METHODS --------------------------
/**
* constructor
*/
@SuppressWarnings( { "WeakerAccess" } )
public FileTransfer()
{
super();
}
/**
* constructor
*
* @param buffSize how big the i/o chunks are to copy files.
*/
public FileTransfer( int buffSize )
{
super( buffSize );
}
/**
* append a file onto the end of another. Works with pure bytes, so can handle binary and text files.
* Does not do anything special to remove ^Z when appending. You can concatenate files with multiple calls
* to append.
*
* @param source file to copy on local hard disk.
* @param target file that will become larger by having source appended to the end of it.
* It need not exist. Source and target must be using the same encoding.
* @return true if the copy was successful.
*/
@SuppressWarnings( { "BooleanMethodNameMustStartWithQuestion", "UnusedDeclaration" } )
public boolean append( File source, File target )
{
if ( source == null )
{
return false;
}
if ( target == null )
{
return false;
}
if ( target.exists() )
{
if ( !target.canWrite() )
{
return false;
}
try
{
// O P E N
FileInputStream is = new FileInputStream( source );
FileOutputStream os = new FileOutputStream( target, true/* append */ );
// C O P Y _ S O U R C E _ T O _ T A R G E T
long fileLength = source.length();
// C L O S E
// handled by inner copy
return copy( is, os, fileLength, true/* close target too */ );
}
catch ( IOException e )
{
return false;
}
}
else // target does not yet exist, just copy.
{
return copy( source, target );
}
}// end append
/**
* Copy a file to an OutputStream
*
* @param source file to copy on local hard disk.
* @param target OutputStream to copy the file to.
* @param closeTarget true if the target OutputStream should be closed when we are done. false if the target
* OutputStream should be left open for further output when done.
* @return true if the copy was successful.
*/
@SuppressWarnings( { "BooleanMethodNameMustStartWithQuestion", "UnusedDeclaration" } )
public boolean copy( File source, OutputStream target, boolean closeTarget )
{
if ( source == null )
{
return false;
}
if ( target == null )
{
return false;
}
try
{
// O P E N
FileInputStream is = new FileInputStream( source );
// C O P Y S O U R C E T O T A R G E T
long fileLength = source.length();
// C L O S E of both both source and target handled by inner copy
return copy( is, target, fileLength, closeTarget );
}
catch ( IOException e )
{
return false;
}
}// end copy
/**
* Copy an InputStream to an OutputStream when you know the length in advance.
*
* @param source InputStream, left closed.
* @param target OutputStream, left closed.
* @param length how many bytes to copy, -1 if you don't know.
* @param closeTarget true if you want the target stream closed when done. false if you want to the target
* stream left open for further output.
* @return true if the copy was successful.
*/
@SuppressWarnings( { "BooleanMethodNameMustStartWithQuestion" } )
public boolean copy( InputStream source,
OutputStream target,
long length,
boolean closeTarget )
{
if ( length <= 0 )
{
// indeterminate length
return copy( source, target, closeTarget );
}
if ( source == null )
{
return false;
}
if ( target == null )
{
return false;
}
try
{
// R E A D / W R I T E by chunks
// we know length > 0
int chunkSize = ( int ) Math.min( buffSize, length );
long chunks = length / chunkSize;
int lastChunkSize = ( int ) ( length % chunkSize );
// code will work even when lastChunkSize = 0 or chunks = 0;
byte[] ba = new byte[chunkSize];
for ( long i = 0; i < chunks; i++ )
{
int bytesRead =
Read.readBytesBlocking( source,
ba,
0,
chunkSize,
readTimeout );
if ( bytesRead != chunkSize )
{
throw new IOException();
}
target.write( ba );
}// end for
// R E A D / W R I T E last chunk, if any
if ( lastChunkSize > 0 )
{
int bytesRead = Read.readBytesBlocking( source,
ba,
0
/* offset in ba */,
lastChunkSize,
readTimeout );
if ( bytesRead != lastChunkSize )
{
throw new IOException();
}
target.write( ba, 0/* offset */, lastChunkSize/* length */ );
}// end if
// C L O S E
source.close();
if ( closeTarget )
{
target.close();
}
return true;
}
catch ( IOException e )
{
return false;
}
}// end copy
/**
* Copy a file from a remote URL to a local file on hard disk. To use this method with a file that requires
* userid/password to access it, see http://mindprod.com/jgloss/authentication.html
*
* @param source remote URL to copy. e.g. new URL("http://www.billabong.com:80/songs/lyrics.txt")
* works with http:, https:, file: and possibly others.
* @param target new file to be created on local hard disk.
* @return true if the copy was successful.
*/
@SuppressWarnings( { "BooleanMethodNameMustStartWithQuestion" } )
public boolean download( URL source, File target )
{
if ( source == null )
{
return false;
}
if ( target == null )
{
return false;
}
try
{
// Not actually connecting yet, just getting connection object,
// urlc will contain subclasses of URLConnection like:
// http: HttpURLConnection
// https: HttpsURLConnectionImpl
// file: FileURLConnection
URLConnection urlc = source.openConnection();
if ( urlc == null )
{
throw new IOException( "Unable to make a connection." );
}
else
{
if ( DEBUGGING )
{
// get simple name of class without the package
String s = urlc.getClass().getName();
// manually chop off all past the last dot.
int lastDot = s.lastIndexOf( '.' );
if ( lastDot >= 0 )
{
s = s.substring( lastDot + 1 );
}
System.out.println( " Connecting to " + source.toString() + " with " + s );
}
}
urlc.setAllowUserInteraction( false );
urlc.setDoInput( true );
urlc.setDoOutput( false );
urlc.setUseCaches( false );
urlc.setReadTimeout( readTimeout );
urlc.setConnectTimeout( connectTimeout );
urlc.setRequestProperty( "Accept",
"text/html, image/png, image/jpeg, image/gif, application/x-java-serialized-object, text/x-java-source, text/xml, application/xml, "
+
"text/css, application/x-java-jnlp-file, text/plain, application/zip, application/octet-stream, *; q=.2, */*; q=.2" );
urlc.connect();
long length = urlc.getContentLength();// -1 if not available
// O P E N _ S O U R C E, raw byte stream
InputStream is = urlc.getInputStream();
// O P E N _ T A R G E T
FileOutputStream os = new FileOutputStream( target );
// C O P Y _ S O U R C E _ T O _ T A R G E T
// C L O S E of InputStream handled by copy. There is no corresponding URLConnection.disconnect
return copy( is, os, length, true/* close target */ );
}
catch ( IOException e )
{
return false;
}
}// end download
// -------------------------- OTHER METHODS --------------------------
/**
* Copy a file from one spot on hard disk to another.
*
* @param source file to copy on local hard disk.
* @param target new file to be created on local hard disk.
* @return true if the copy was successful.
*/
@SuppressWarnings( { "BooleanMethodNameMustStartWithQuestion" } )
boolean copy( File source, File target )
{
if ( source == null )
{
return false;
}
if ( target == null )
{
return false;
}
try
{
// O P E N
FileInputStream is = new FileInputStream( source );
FileOutputStream os = new FileOutputStream( target );
// C O P Y S O U R C E T O T A R G E T
long fileLength = source.length();
// C L O S E
// handled by inner copy
return copy( is, os, fileLength, true );
}
catch ( IOException e )
{
return false;
}
}// end copy
// --------------------------- main() method ---------------------------
/**
* dummy main
*
* @param args not used source url, target file
*/
public static void main( String[] args )
{
System.err
.println(
"FileTransfer is not intended to be run from the command line. See Download." );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -