📄 minifiletransfer.java
字号:
/*
version 1.0 1999 Sept 5 - implement download and copy.
* - use of readBytesBlocking to replace readFully and read.
* version 1.1 1999-10-05- implement upload with PUT, and a status check.
* version 1.2 1999-10-26 - split into MiniFileTransfer, FileTransfer,
* and MaxiFileTransfer
* - added support for ZipFile entry download.
* version 1.3 1999-10-28 - add safety code when length specified
* is -1 or 0, to copy as if the length were unknown.
version 1.4 1999-10-29 - ensure every file closed, including ZipFile
- safety check for null parms.
version 1.5 2001-01-23 - use more elegant
* reads in the while loops instead of breaks.
* Version 1.6 2002-04-22 - conforming package name.
* Version 1.7 2003-09-15 -
* add closeTarget parameter to many methods
* - rename download( InputStream, File ) to copy( InputStream , File ) - add copy( File,
* OutputStream )
* Version 1.8 2006-01-10 add Download class.
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.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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* download a file, fishing it out of either this or another jar. 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. If you make more than casual use, please
* sent a registration fee of $10 either US or Canadian to: FILETRANSFER REGISTRATIONS Roedy Green Canadian Mind
* Products #101 - 2536 Wark Street Victoria, BC Canada V8T 4G8 roedy g at mindprod dotcom http://mindprod.com "More
* that casual use" would include using FileTransfer in a commercial product or using it in a project deployed on more
* than 5 computers. The registration requirement is not onerous. You need register only one copy. Make sure you have
* the latest version from http://mindprod.com.
*
* @author copyright (c) 1999-2008 Roedy Green, Canadian Mind Products may be copied and used freely for any purpose but
* military.
* <p/>
* 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
*/
@SuppressWarnings( { "WeakerAccess" } )
public class MiniFileTransfer
{
// ------------------------------ FIELDS ------------------------------
/**
* true if want debugging output
*/
static final boolean DEBUGGING = false;
/**
* default size of chunks to transfer at a time.
*/
private static final int DEFAULT_BUFFSIZE = 63 * 1024;
/**
* size of chunks to transfer at a time.
*/
final int buffSize;
/**
* Allow 50 seconds to connect
*/
int connectTimeout = 50 * 1000;
/**
* Allow 40 seconds for a read to go without progress
*/
int readTimeout = 40 * 1000;
// -------------------------- PUBLIC INSTANCE METHODS --------------------------
/**
* constructor
*/
@SuppressWarnings( { "WeakerAccess" } )
public MiniFileTransfer()
{
this.buffSize = DEFAULT_BUFFSIZE;
}
/**
* constructor
*
* @param buffSize how big the i/o chunks are to copy files.
*/
public MiniFileTransfer( int buffSize )
{
if ( buffSize < 512 )
{
buffSize = 512;
}
this.buffSize = buffSize;
}
/**
* copy a file from a stream, typically a resource in the archive jar file to a local file on hard disk.
*
* @param source resource as stream e.g. this.class.getResourceAsStream("lyrics.ram"); Netscape interferes with
* extensions *.exe, *.dll etc. So use *.ram for your resources.
* @param target new file to be created on local hard disk.
* @return true if the copy was successful.
*/
@SuppressWarnings( { "BooleanMethodNameMustStartWithQuestion", "WeakerAccess" } )
public boolean copy( InputStream source, File target )
{
if ( source == null )
{
return false;
}
if ( target == null )
{
return false;
}
final FileOutputStream os;
try
{
// O P E N _ T A R G E T
os = new FileOutputStream( target );
// C O P Y _ S O U R C E _ T O _ T A R G E T
return copy( source, os, true );
// C L O S E
// handled by copy.
}
catch ( IOException e )
{
return false;
}
}// end download
/**
* Copy an InputStream to an OutputStream, until EOF. Use only when you don't know the length of the transfer ahead
* of time. Otherwise use FileTransfer.copy.
*
* @param source InputStream, always left closed
* @param target OutputStream
* @param closeTarget true if you want target stream closed when done. false, leave the target open for more I/O.
* @return true if the copy was successful.
*/
@SuppressWarnings( { "NestedAssignment", "BooleanMethodNameMustStartWithQuestion" } )
public boolean copy( InputStream source,
OutputStream target,
boolean closeTarget )
{
if ( source == null )
{
return false;
}
if ( target == null )
{
return false;
}
try
{
// R E A D / W R I T E by chunks
int chunkSize = buffSize;
// code will work even when chunkSize = 0 or chunks = 0;
// Even for small files, we allocate a big buffer, since we
// don't know the size ahead of time.
byte[] ba = new byte[chunkSize];
// keep reading till hit eof
int bytesRead;
while ( ( bytesRead =
Read.readBytesBlocking( source,
ba,
0,
chunkSize,
readTimeout ) ) > 0 )
{
target.write( ba, 0/* offset */, bytesRead/* len */ );
}// end while
// C L O S E
source.close();
if ( closeTarget )
{
target.close();
}
}
catch ( IOException e )
{
return false;
}
// all was ok
return true;
}// end copy
/**
* Copy a file from a resource in some a local jar file, not the archive, to a local file on hard disk. To deal with
* remote jars in JDK 1.1 download the entire jar, then copy the various contents to their resting places, then
* delete the jar. To deal with remote jars in JDK 1.2 use the new jar URL syntax, that lets you treat a member as
* if it were an separate file, jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class
*
* @param sourceJar ZipFile e.g. new ZipFile("stuff.jar"), left open.
* @param zipEntryString fully qualified name of ZipEntry e.g. "com/mindprod/mypack/Stuff.html". Note this is a
* String, not a ZipEntry.
* @param target new file to be created on local hard disk.
* @return true if the copy was successful.
*/
@SuppressWarnings( { "BooleanMethodNameMustStartWithQuestion" } )
public boolean copy( ZipFile sourceJar, String zipEntryString, File target )
{
if ( sourceJar == null )
{
return false;
}
if ( zipEntryString == null )
{
return false;
}
if ( target == null )
{
return false;
}
try
{
ZipEntry zipEntry = sourceJar.getEntry( zipEntryString );
if ( zipEntry == null )
{
return false;
}
InputStream is = sourceJar.getInputStream( zipEntry );
return is != null && copy( is, target );
// C L O S E
// download closes is and target
// don't close entire zip with sourceJar.close();
}
catch ( IOException e )
{
return false;
}
}// end copy
/**
* override the default connect timeout of 50 seconds
*
* @param connectTimeout timeout to connect in ms. Note int not long.
*/
public void setConnectTimeout( int connectTimeout )
{
this.connectTimeout = connectTimeout;
}
/**
* override the default read timeout of 40 seconds
*
* @param readTimeout timeout to connect int ms. Note int not long.
*/
public void setReadTimeout( int readTimeout )
{
this.readTimeout = readTimeout;
}
// --------------------------- main() method ---------------------------
/**
* dummy main
*
* @param args not used source url, target file
*/
public static void main( String[] args )
{
System.err
.println(
"MiniFileTransfer is not intended to be run from the command line. See Download." );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -