Java: Upload file from URL directly to FTP server with a library - java

It is possible to transfer a file from a url (http://... .exe/ .zip ...) directly to a ftp server in Java 7 (with some additional libraries eg from Apache?

There is support for both HTTP and at least limited FTP support through the standard API class java.net.URL. You have only restricted access to specific FTP features like setting the transfer mode, but in most cases it works.
If you add Apache Commons IO, you can use the IOUtils class to copy directly from the HTTP server to the FTP server:
InputStream in = new URL("http://host/path").openStream();
OutputStream out =
new URL("ftp://user:pass#host/path").openConnection().getOutputStream();
IOUtils.copy(in, out);
in.close();
out.close();
If you don't want to add a dependency on Commons IO, you just have to write a few lines to copy the data without 3rd party library support:
byte[] buffer = new byte[16384];
int r = 0;
while ((r=in.read(buffer))>=0) {
out.write(buffer, 0, r);
}

I don't believe it's possible in general to instruct a web server to upload a file directly to an FTP server, but it's definitely possible to write a program to download the file yourself and then upload it to an FTP server.

Related

FTP File Upload - Filename Encoding Error

I'm using apache's commons-net 3.5 to upload files to a remote FTP server, and setting the connection encoding to UTF-8 like below, before openning the connection.
ftpClient.setAutodetectUTF8(true);
ftpClient.setControlEncoding("UTF-8");
And this is the part that sends the file
private void uploadFile(byte[] data, String path, String fileName, FTPClient ftpClient) throws IOException {
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.setFileTransferMode(FTPClient.BINARY_FILE_TYPE);
boolean uploadSuccess = ftpClient.storeUniqueFile(fileName, new ByteArrayInputStream(data));
Here is the problem; when sending files whose name contains Turkish characters, the result file is named incorrectly. Like,
Kimlikş.pdf -> KimlikÅ.pdf
But if I use ftp4j, everything works fine. Did anyone have this before? The data ships incrorrectly from my side. I monitored the traffic with Microsoft Network Monitor. Here is the raw request:
FTP FTP:Request from Port 62642,'STOR KimlikÅ.pdf' {TCP:5879, IPv4:134}
try to use WinSCP - it was working like a charm.
https://winscp.net/eng/download.php
no FileZilla, no TotalCommander - only WinSCP.
and by copy again (for example I had about 6k files and only 50 with cyrilic) only give at question prompt "no to all" and WinSCP copies only left files. great !
5 stars to the free software !
I guess there was a bug with apache's commons-net, so I migrated to ftp4j and the problem was no more.
<dependency>
<groupId>it.sauronsoftware</groupId>
<artifactId>ftp4j</artifactId>
<version>1.6</version>
</dependency>

Accessing Remote files using HTTP from a web application

we have a requirement where all file (text , image , PDF etc) uploaded in the Server1. Now we have a Java web application running in a different server (Server 2) which has to read these files and show it in the GUI.
FTP is blocked in web application server. So i am thinking of using HTTP.
The files in Server1 is not distributed .i.e not inside any ear or war.
I managed to get the code to read a file from HTTP.
My question is
- How do i access this file through HTTP when these files are not distributed
- When i write a code accessing the file like http://server1:port1/location of file , its says file not found .
- how do i expose these files , so that i can access it via HTTP from my web application
That means, you want to download the content of the file.
Well at very first, open up a browser. Enter http://server1:port1/FILE_PATH .
what do you get as a response ?
Second, if you get "FILE NOT FOUND" then you need to configure a virtual path mapped to real path in server1. After that, try the URL from browser again. When it works,
URL website = new URL("http://server1/file_location");
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream("file_name");
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
will help you to download the file to your local machine.

JSch, lock file while session is open

Is there any way to lock file, which i am reading with JSch sftp channel, to prevent other applications to modificate it while session is open?
The problem i have: while i am reading/writing file, some other application changes the file and its causes errors.
Currently i am reading file in such way:
ChannelSftp sftp = (ChannelSftp) session.openChannel("sftp");
InputStream stream = sftp.get("/some/file");
try {
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
// read from br
} finally {
stream.close();
}
Rather than locking the file (which could adversely affect whatever application you suggest is changing the file), and presuming you have ssh access and permissions to do so you could copy the file into a temp file using an ssh command (if on a 'nix system: 'cp /some/file/ /some/temp/file/'), which in all likelihood will be much faster than transferring via scp. (See http://www.jcraft.com/jsch/examples/Exec.java.html for exec example). From there, scp-get the temp file. Lastly, if necessary, delete the temp file via an other JSch exec command.
Jsch at this time supports version 3 of the SFTP protocol. The wikipedia page contains links to different versions of the protocol. Version 3 is here, and the word "lock" doesn't appear anywhere in it. In other words, the protocol doesn't support locking, so there's nothing for Jsch to support.
SFTP versions 5 and 6 do contain support for locking remote files. However, Jsch doesn't support these protocol versions.
I'll add that OpenSSH, the most widely used SSH/SFTP server, only supports SFTP version 3. You'd have to use some other server software to have any hope of doing file locks.

0 kb file created once FTP is done in java

I am trying to FTP a file on to a remote machine. Below is my code :-
FTPClient ftpClient = new FTPClient();
ftpClient.connect("home.abc.com");
ftpClient.login("remote", "guesst12");
int replyCode = ftpClient.getReplyCode();
ftpClient.changeWorkingDirectory("share"))
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
InputStream input = new FileInputStream(new File("H:/testFile.txt"));
OutputStream out = ftpClient.storeFileStream("testFile.txt");
Util.copyStream(input, out);
out.close();
input.close();
ftpClient.completePendingCommand()
ftpClient.logout();
ftpClient.disconnect();
When i execute this piece of code, the code is executed without any issues, but at the remote machine, when i check the file, the file is being created, but with no content (OKB) file. Am i missing something in code.
[Update] :
I tried with the following code for storing file :-
if(ftpClient.storeFile("testCopy.txt", input)) {
System.out.println("File Stored Successfully");
}
System.out.println(ftpClient.getReplyString());
Now the reply code i recieved is :- 451 Failure writing to local file. What does that means.
Thanks
After looking at it over and over I keep coming up with different things.
Are you sure that the InputStream is reading the file before your copying the stream? Because I'm not sure FileInputStream read's the file on initiation.
I suspect that the problem is inUtil.copyStream, which code you didn't provide. I highly recommend that you use IOutils from Apache Commons IO to copy streams.
Looking at older questions here with similar problems, it looks like you hit a bug of the Commons-NET library (of which the FTPClient is a part).
Try to install a newer version (3.0.1 or later), or an earlier version (2.2) to fix this.
One of the reasons running into FTP error 451 when trying to copy a file over FTP
especially if you see 0 sized file created on the server side,
is probably due to No Space on Disk.

Should retrieveFile of commons FTPClient remove file from remote server

We are using Commons FTPClient to retrieve files from an ftp server. Our code is similar to:
FTPClient ftpClient= new FTPClient();
ftpClient.connect(server);
ftpClient.login(username, password);
FileOutputStream out = new FileOutputStream(localFile);
ftpClient.retrieveFile(remoteFile, out)
When we run this code the file is moved from the FTP Server instead of copied. Just wondering is this expected behavior?
If this is expected behavior what is the best approach to retrieve a copy of the file from the server but leave a copy of the file on the server? (We do not have access to write to the FTP Server so we cannot write the file back to the server)
Any help appreciated,
Thanks
It is very strange behavior. I have just examined the code of FTPClient and did not see something that may remove the remote file. I believe that this is a configuration of your FTP server.
To check it I'd recommend you to try other FTP client. For example unix command line utility ftp or fget or regular web browser.
I wish you good luck.

Categories

Resources