Java and FTP to edit online text files - java

In my Java swing program, I read, edit and save various text files in a local folder using Scanner and BufferedWriter. Is there an easy way I can keep my current code, but, using FTP, edit a web file rather than a local file? Thanks everyone.

You can use the URL and URLConnection classes to obtain InputStreams and OutputStreams to files located on an FTP Server.
To read a file
URL url = new URL("ftp://user:pass#my.ftphost.com/myfile.txt");
InputStream in = url.openStream();
to write a file
URL url = new URL("ftp://user:pass#my.ftphost.com/myfile.txt");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStream out = conn.getOutputStream();

I tried to achieve the same and the answers to those questions helped me a lot:
Adding characters to beginning and end of InputStream in Java (the one marked as right shows how to add a custom string to the InputStream)
Uploading a file to a FTP server from android phone? (the one from Kumar Vivek Mitra shows how to upload a file)
I added new text to the end of my online file like this:
FTPClient con = null;
try {
con = new FTPClient();
con.connect(Hostname);
if (con.login(FTPUsername, FTPPassword)) {
con.enterLocalPassiveMode(); // important!
con.setFileType(FTP.BINARY_FILE_TYPE);
InputStream onlineDataIS = urlOfOnlineFile.openStream();
String end = "\nteeeeeeeeeeeeeeeeest";
List<InputStream> streams = Arrays.asList(
onlineDataIS,
new ByteArrayInputStream(end.getBytes()));
InputStream resultIS = new SequenceInputStream(Collections.enumeration(streams));
// Stores a file on the server using the given name and taking input from the given InputStream.
boolean result = con.storeFile(PathOfTargetFile, resultIS);
onlineDataIS.close();
resultIS.close();
if (result) Log.v("upload result", "succeeded");
con.logout();
con.disconnect();
}
return "Writing successful";
} catch (IOException e) {
// some smart error handling
}
Hope that helps.

Related

How to Pass a File through an HttpURLConnection

I'm trying to get an image hosting on our server available to be displayed on a client. As per the specs of the project:
"When a Client receives such a URL, it must download the
contents (i.e., bytes) of the file referenced by the URL.
Before the Client can display the image to the user, it must first retrieve (i.e., download) the bytes of the
image file from the Server. Similarly, if the Client receives the URL of a known data file or a field help file
from the Server, it must download the content of those files before it can use them."
I'm pretty sure we have the server side stuff down, because if I put the url into a browser it retrieves and displays just fine. So it must be something with the ClientCommunicator class; can you take a look at my code and tell me what the problem is? I've spent hours on this.
Here is the code:
Where I actually call the function to get and display the file: (This part is working properly insofar as it is passing the right information to the server)
JFrame f = new JFrame();
JButton b = (JButton)e.getSource();
ImageIcon image = new ImageIcon(ClientCommunicator.DownloadFile(HOST, PORT, b.getLabel()));
JLabel l = new JLabel(image);
f.add(l);
f.pack();
f.setVisible(true);
From the ClientCommunicator class:
public static byte[] DownloadFile(String hostname, String port, String url){
String image = HttpClientHelper.doGetRequest("http://"+hostname+":"+port+"/"+url, null);
return image.getBytes();
}
The pertinent httpHelper:
public static String doGetRequest(String urlString,Map<String,String> headers){
URL url;
HttpURLConnection connection = null;
try {
//Create connection
url = new URL(urlString);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches (false);
connection.setDoInput(true);
connection.setDoOutput(true);
if(connection.getResponseCode() == 500){
return "failed";
}
//Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
response.append(line);
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if(connection != null) {
connection.disconnect();
}
}
}
After that, it jumps into the server stuff, which as I stated I believe is working correctly because clients such as Chrome can retrieve the file and display it properly. The problem has to be somewhere in here.
I believe that it has to do with the way the bytes are converted into a string and then back, but I do not know how to solve this problem. I've looked at similar problems on StackOverflow and have been unable to apply them to my situation. Any pointers in the right direction would be greatly appreciated.
If your server is sending binary data, you do not want to use an InputStreamReader, or in fact a Reader of any sort. As the Java API indicates, Readers are for reading streams of characters (not bytes) http://docs.oracle.com/javase/7/docs/api/java/io/Reader.html, which means you will run into all sorts of encoding issues.
See this other stack overflow answer for how to read bytes from a stream:
Convert InputStream to byte array in Java
Do your homework.
Isolate the issue. Modify the server side to send only 256 all possible bytes. Do a binary search and reduce it to small set of bytes.
Use http proxy tools to monitor the bytes as they are transmitted. Fiddler in windows world. Find other ones for the *nix environments.
Then see where the problem is happening and google/bing the suspicions or share the result.

Mysterious FileNotFoundException

I´m writing an Android app that communicates with a Tomcat Server running servlets. I´m doing a POST to the Tomcat server, specifying what file I want the server to send back to the client (the Android app). When I try to open this file by adding the file name sent with the POST to the catalog name I get a FileNotFoundException. But hardcoding exactly the same file name works just fine.
Copy pasting the file path obtained when the FileNotFoundException is thrown from the Tomcat servers console into windows explorer opens the correct file. I also wrote both the hardcoded file path, and the one where I append the file name to the catalog path, to a log file. In this log file both texts look exactly the same, and copy pasting both of them into windows explorer opens the correct file. Does anybody have an idea why this yields a FileNotFoundException?
Doing the post from client side
String potentialIP = "http://"+url+":8080/se.myPage/myServlet";
URL url = new URL(potentialIP);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setChunkedStreamingMode(0);
// Starts the query
conn.connect();
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
byte[] byteArray = korning.getBytes();
out.write(byteArray);
out.flush();
And the doPost method on the server side looks like this
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
InputStream in = request.getInputStream();
java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\A");
String fileName = s.hasNext() ? s.next() : "";
String filePath = "C:/myCatalog/"+fileName;
PrintWriter out = response.getWriter();
PrintWriter writer = new PrintWriter("C:/myCatalog/Servletlog.txt", "UTF-8");
writer.write("'"+"C:/myCatalog/hardCodedFileName.txt"+"'");
writer.write("'"+filePath+"'");
writer.flush();
writer.close();
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String svar = reader.readLine();
reader.close();
out.close();
}
Anybody got an idea on how to solve this?
For me it turns out that the server was blocking whatever the default user agent is (maybe it was nothing) and was returning 403. And this throws the FileNotFoundException on my try. I then changed to an example json from another server: http://date.jsontest.com/
This will return a json that looks like this:
{
"time": "05:58:38 AM",
"milliseconds_since_epoch": 1400047118645,
"date": "05-14-2014"
}
By switching to another Server everything worked great - later I figured out that there is a problem with (as I said above) the user agent - set it to something like the Chrome user agent and it also should work normally.
Hope it will help you.

Java Applet hangs in IE when getting HttpUrlConnection outputstream

I have a signed file uploader applet that works in Chrome but seems to hang when run in IE. In IE, I can successfully upload a file (or set of files) one time but the next time I try to upload another file, the browser freezes and I have to close the browser. It seems to be happening when I attempt to retrieve the outputstream of the HttpUrlConnection object. Here is my code:
public void upload(URL url, URL returnUrl, List<FileIconPanel> files) {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setChunkedStreamingMode(1024);
HttpURLConnection.setFollowRedirects(false);
conn.setRequestProperty("content-type", "application/zip");
conn.setRequestMethod("POST");
//This zip output stream will server as our stream to the server and will zip each file while
// it sends it to the server.
ZipOutputStream out = new ZipOutputStream(conn.getOutputStream());
for (int i = 0; i < files.size(); i++) {
//For each file we will create a new entry in the ZIP archive and stream the file into that entry.
File f = (File) files.get(i).getFile();
ZipEntry entry = new ZipEntry(f.getName());
out.putNextEntry(entry);
InputStream in = new FileInputStream(f);
int read;
byte[] buf = new byte[1024];
while ((read = in.read(buf)) > 0) {
out.write(buf, 0, read);
}
out.closeEntry();
}
//Once we are done writing out our stream we will finish building the archive and close the stream.
out.finish();
out.close();
// Now that we have set all the connection parameters and prepared all
// the data we are ready to connect to the server.
conn.connect();
// read & parse the response
InputStream is = conn.getInputStream();
StringBuilder response = new StringBuilder();
byte[] respBuffer = new byte[4096];
while (is.read(respBuffer) >= 0) {
response.append(new String(respBuffer).trim());
}
is.close();
} catch (IOException ioE) {
ioE.printStackTrace();
logger.info("An unexpected exception has occurred. Contact your system administrator");
} catch (Exception e) {
e.printStackTrace();
logger.info("An unexpected exception has occurred. Contact your system administrator");
} finally {
//Once we are done we want to make sure to disconnect from the server.
if (conn != null) conn.disconnect();
}
}
I can see in the log files that it is freezing a this line:
ZipOutputStream out = new ZipOutputStream(conn.getOutputStream());
the second time I try to upload a file. This code also does work in IE under java 6. It has had this problem since I updated to the latest.
Is there something I'm leaving open that I need to make sure to close out before using the applet again? Been beating my head against this for the last two days. Sure hope someone can help...
I have an idea of what's going on but I don't know exactly the details of the what's causing the problem. I at least figured it out a workaround...I was using a jquery dialog box to display the applet. I was doing this on the fly so every time I open the dialog box, it was building the applet again. It's strange because I was in fact removing the div element that contained the applet every time the dialog box was closed so I would have thought that would ensure the old applet instance was destroyed as well. Chrome seems to be smart enough to destroy it and create a new one (or something to that effect) but IE has problems.

java code to download a file from server

using java code in windows i need to download several files from a directory placed in a server. those files in server are generated separately. so i'll not know the name of those files. is there any way to download it using JAVA and saving it in a specific folder.
i am using apache tomcat.
I read all other threads related to java file download. But none of them satisfy my requirement.
try {
// Get the directory and iterate them to get file by file...
File file = new File(fileName);
if (!file.exists()) {
context.addMessage(new ErrorMessage("msg.file.notdownloaded"));
context.setForwardName("failure");
} else {
response.setContentType("APPLICATION/DOWNLOAD");
response.setHeader("Content-Disposition", "attachment"+
"filename=" + file.getName());
stream = new FileInputStream(file);
response.setContentLength(stream.available());
OutputStream os = response.getOutputStream();
os.close();
response.flushBuffer();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope you got some idea...
Use java.net.URL and java.net.URLConnection classes.
Hi you can use this following code snippet to down the file directly :
URL oracle = new URL("http://www.example.com/file/download?");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
Kindly refer about openStream in this [URL] : http://docs.oracle.com/javase/tutorial/networking/urls/readingURL.html
You can use HttpURLConnection to download file over HTTP, HTTPS
It is only possible if server lists directory contents. if it does, your can make an HTTP request to:
http://server:port/folder
that would give you list of files.
Once you have that, you can download individual files by parsing output if this http request.
If it is server, then the process must be like using the FTP credentials you have to dosnload the files. This java file download example may help you.

How do I do an FTP delete with Java URLConnection?

I have a simple put and get working, but can't seem to find how to do a delete? For reference, the put code is:
BufferedInputStream inStream = null;
FileOutputStream outStream = null;
try {
final String ftpConnectInfo = "ftp://"+user+":"+pass+"#"+destHost+"/"+destFilename+";type=i";
LOGGER.info("Connection String: {}", ftpConnectInfo);
URL url = new URL(ftpConnectInfo);
URLConnection con = url.openConnection();
inStream = new BufferedInputStream(con.getInputStream());
outStream = new FileOutputStream(origFilename);
int i = 0;
byte[] bytesIn = new byte[1024];
while ((i = inStream.read(bytesIn)) >= 0) {
outStream.write(bytesIn, 0, i);
}
}
Is there some way to modify the URL to do a delete?
Based on this discussion on JavaRanch, I'm not sure you can do it by just modifying the URL. Is there any particular reason why you're not just using a library class like Apache commons FTPClient?
I would take a look at commons-net or commons-vfs for Java FTP, what you are doing here is opening an input stream on a file and reading it, while you want to send a command and get an acknowledgment.
I think the URLConnection is just supposed to allow you to read data.
It implements some commands of the FTP protocol to allow you to fetch files. But i don't think there is any way to sneakily encode a DELETE command in a URL to allow you to do what you want.
As other have said: you have to use a full featured FTP client.

Categories