📄 ftpclient.java
字号:
* appending if current file exists
*
* @param bytes array of bytes
* @param remoteFile name of remote file in
* current directory
* @param append true if appending, false otherwise
*/
public void put(byte[] bytes, String remoteFile, boolean append)
throws IOException, FTPException {
initPut(remoteFile, append);
// get an output stream
BufferedOutputStream out =
new BufferedOutputStream(
new DataOutputStream(data.getOutputStream()));
try {
// write array
out.write(bytes, 0, bytes.length);
}
finally {
// flush and clean up
try {
out.flush();
//out.close(); // Hans
}
catch (IOException ignore) {}
closeDataSocket();
}
validateTransfer();
}
/**
* Get data from the FTP server. Uses the currently
* set transfer mode.
*
* @param localPath local file to put data in
* @param remoteFile name of remote file in
* current directory
*/
public void get(String localPath, String remoteFile)
throws IOException, FTPException {
// get according to set type
if (getType() == FTPTransferType.ASCII) {
getASCII(localPath, remoteFile);
}
else {
getBinary(localPath, remoteFile);
}
validateTransfer();
}
/**
* Get data from the FTP server. Uses the currently
* set transfer mode.
*
* @param destStream data stream to write data to
* @param remoteFile name of remote file in
* current directory
*/
public void get(OutputStream destStream, String remoteFile)
throws IOException, FTPException {
// get according to set type
if (getType() == FTPTransferType.ASCII) {
getASCII(destStream, remoteFile);
}
else {
getBinary(destStream, remoteFile);
}
validateTransfer();
}
/**
* Request to the server that the get is set up
*
* @param remoteFile name of remote file
*/
private void initGet(String remoteFile)
throws IOException, FTPException {
checkConnection(true);
// reset the cancel flag
cancelTransfer = false;
boolean close = false;
data = null;
try {
// set up data channel
data = control.createDataSocket(connectMode);
data.setTimeout(timeout);
// if resume is requested, we must issue REST
if (resume) {
if (transferType.equals(FTPTransferType.ASCII))
throw new FTPException("Resume only supported for BINARY transfers");
restart(resumeMarker);
}
// send the retrieve command
FTPReply reply = control.sendCommand("RETR " + remoteFile);
// Can get a 125 or a 150
String[] validCodes1 = {"125", "150"};
lastValidReply = control.validateReply(reply, validCodes1);
}
catch (IOException ex) {
close = true;
throw ex;
}
catch (FTPException ex) {
close = true;
throw ex;
}
finally {
if (close) {
resume = false;
closeDataSocket();
}
}
}
/**
* Get as ASCII, i.e. read a line at a time and write
* using the correct newline separator for the OS
*
* @param localPath full path of local file to write to
* @param remoteFile name of remote file
*/
private void getASCII(String localPath, String remoteFile)
throws IOException, FTPException {
// B.McKeown:
// Call initGet() before creating the FileOutputStream.
// This will prevent being left with an empty file if a FTPException
// is thrown by initGet().
initGet(remoteFile);
// B. McKeown: Need to store the local file name so the file can be
// deleted if necessary.
File localFile = new File(localPath);
// create the buffered stream for writing
BufferedWriter out =
new BufferedWriter(
new FileWriter(localPath));
// get an character 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
LineNumberReader in =
new LineNumberReader(
new BufferedReader(
new InputStreamReader(data.getInputStream())));
// B. McKeown:
// If we are in active mode we have to set the timeout of the passive
// socket. We can achieve this by calling setTimeout() again.
// If we are in passive mode then we are merely setting the value twice
// which does no harm anyway. Doing this simplifies any logic changes.
data.setTimeout(timeout);
// output a new line after each received newline
IOException storedEx = null;
long size = 0;
long monitorCount = 0;
try {
int ch = -1;
while ((ch = readChar(in)) != -1 && !cancelTransfer) {
size++;
monitorCount++;
if (ch == '\n')
out.newLine();
else
out.write(ch);
if (monitor != null && monitorCount > monitorInterval) {
monitor.bytesTransferred(size);
monitorCount = 0;
}
}
}
catch (IOException ex) {
storedEx = ex;
localFile.delete();
}
finally {
out.close();
}
closeDataSocket();
// if we failed to write the file, rethrow the exception
if (storedEx != null)
throw storedEx;
else if (monitor != null) // notify final size
monitor.bytesTransferred(size);
}
/**
* Get as ASCII, i.e. read a line at a time and write
* using the correct newline separator for the OS
*
* @param destStream data stream to write data to
* @param remoteFile name of remote file
*/
private void getASCII(OutputStream destStream, String remoteFile)
throws IOException, FTPException {
initGet(remoteFile);
// create the buffered stream for writing
BufferedWriter out =
new BufferedWriter(
new OutputStreamWriter(destStream));
// get an character input stream to read data from ... AFTER we
// have the ok to go ahead
LineNumberReader in =
new LineNumberReader(
new BufferedReader(
new InputStreamReader(data.getInputStream())));
// B. McKeown:
// If we are in active mode we have to set the timeout of the passive
// socket. We can achieve this by calling setTimeout() again.
// If we are in passive mode then we are merely setting the value twice
// which does no harm anyway. Doing this simplifies any logic changes.
data.setTimeout(timeout);
// output a new line after each received newline
IOException storedEx = null;
long size = 0;
long monitorCount = 0;
try {
int ch = -1;
while ((ch = readChar(in)) != -1 && !cancelTransfer) {
size++;
monitorCount++;
if (ch == '\n')
out.newLine();
else
out.write(ch);
if (monitor != null && monitorCount > monitorInterval) {
monitor.bytesTransferred(size);
monitorCount = 0;
}
}
}
catch (IOException ex) {
storedEx = ex;
}
finally {
out.close();
}
closeDataSocket();
// if we failed to write the file, rethrow the exception
if (storedEx != null)
throw storedEx;
else if (monitor != null)
monitor.bytesTransferred(size);
}
/**
* Get as binary file, i.e. straight transfer of data
*
* @param localPath full path of local file to write to
* @param remoteFile name of remote file
*/
private void getBinary(String localPath, String remoteFile)
throws IOException, FTPException {
// B. McKeown: Need to store the local file name so the file can be
// deleted if necessary.
File localFile = new File(localPath);
// if resuming, we must find the marker
if (localFile.exists() && resume)
resumeMarker = localFile.length();
// B.McKeown:
// Call initGet() before creating the FileOutputStream.
// This will prevent being left with an empty file if a FTPException
// is thrown by initGet().
initGet(remoteFile);
// create the buffered output stream for writing the file
BufferedOutputStream out =
new BufferedOutputStream(
new FileOutputStream(localPath, resume));
// 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
BufferedInputStream in =
new BufferedInputStream(
new DataInputStream(data.getInputStream()));
// B. McKeown:
// If we are in active mode we have to set the timeout of the passive
// socket. We can achieve this by calling setTimeout() again.
// If we are in passive mode then we are merely setting the value twice
// which does no harm anyway. Doing this simplifies any logic changes.
data.setTimeout(timeout);
// do the retrieving
long size = 0;
long monitorCount = 0;
byte [] chunk = new byte[transferBufferSize];
int count;
IOException storedEx = null;
// read from socket & write to file in chunks
try {
while ((count = readChunk(in, chunk, transferBufferSize)) >= 0 && !cancelTransfer) {
out.write(chunk, 0, count);
size += count;
monitorCount += count;
if (monitor != null && monitorCount > monitorInterval) {
monitor.bytesTransferred(size);
monitorCount = 0;
}
}
}
catch (IOException ex) {
storedEx = ex;
localFile.delete();
}
finally {
out.close();
}
resume = false;
// close streams
closeDataSocket();
// if we failed to write the file, rethrow the exception
if (storedEx != null)
throw storedEx;
else if (monitor != null)
monitor.bytesTransferred(size);
// log bytes transferred
log.debug("Transferred " + size + " bytes from remote host");
}
/**
* Get as binary file, i.e. straight transfer of data
*
* @param destStream stream to write to
* @param remoteFile name of remote file
*/
private void getBinary(OutputStream destStream, String remoteFile)
throws IOException, FTPException {
initGet(remoteFile);
// create the buffered output stream for writing the file
BufferedOutputStream out =
new BufferedOutputStream(destStream);
// 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
BufferedInputStream in =
new BufferedInputStream(
new DataInputStream(data.getInputStream()));
// B. McKeown:
// If we are in active mode we have to set the timeout of the passive
// socket. We can achieve this by calling setTimeout() again.
// If we are in passive mode then we are merely setting the value twice
// which does no harm anyway. Doing this simplifies any logic changes.
data.setTimeout(timeout);
// do the retrieving
long size = 0;
long monitorCount = 0;
byte [] chunk = new byte[transferBufferSize];
int count;
IOException storedEx = null;
// read from socket & write to file in chunks
try {
while ((count = readChunk(in, chunk, transferBufferSize)) >= 0 && !cancelTransfer) {
out.write(chunk, 0, count);
size += count;
monitorCount += count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -