I'm using the acm libraries for my Java program, and I want to embed my program into my website via HTML. I have other .jar files embedded just fine in my website, by using the
<applet archive="file.jar, acm.jar"
code="main.class"
width=400 height=600 />
but have found that when embedded in HTML the program sort of freaks out and stops responding when it gets to the part where it should load the .txt file.
I remember vaguely my AP CompSci teacher telling us that java in web browsers blocked the import of .txt files, but I might be remembering incorrectly. Here is my java code below:
public NameSurferDataBase(String filename) {
nameEntry = new HashMap<String, NameSurferEntry>();
try {
BufferedReader rd = new BufferedReader(new FileReader(filename));
while (true) {
String line = rd.readLine();
if (line == null) break;
NameSurferEntry entry = new NameSurferEntry(line);
nameEntry.put(entry.getName().toUpperCase(), entry);
}
} catch (IOException ex) {
throw new ErrorException(ex);
}
}
So not only do I not know how to actually add the .txt file as something to use before it runs, I don't even know if it is possible.
It's because when running applets, the security manager doesn't let you work with the filesystem (unless you specifically change the plugin settings which is a bad idea). If you're just trying to read, put the file in your classpath, and use ClassLoader.getResourceAsStream(String resource) to get the input stream instead.
Related
I'm actually not that great and am relatively new at Java. I wish to receive input from the user, and want to input this data into an external application.
This application processes the data and provides an output. I wish to retrieve this output using the Java code.
I have attempted in doing this but, I haven't got the slightest idea on how to start this script.
Nothin' on the internet seems to answer this question. If you have any idea or any new functions that can be useful, please help me in doing so.
Since I'm starting from ground zero, any help is appreciated.
Thanks so much.
To communicate with an external application you need to first define the communication way. For example:
Will this application read the output from a file?
If that statement it's true, then you need to learn serialization:
Will this application read the input from the standard output (like a command-line application)
If that statement it's true then you need to send with System.out.print().
Will this application get the data over HTTP.
Then you need to learn about REST and or RPC architectures.
Assuming that it will be a command-line application, then you could use something like this:
public class App
{
public static void main(String... args)
{
// You need to implement your business logic here. Not just print whatever the user passes as arguments of the command-line.
for(String arg : args)
{
System.out.print(arg);
}
}
}
There's a lot going on here but I'll suggest an example for each part of this question and assume this is just going to be written in Java, and suggesting an iterative design/development approach.
receive input from the user::getting arguments from the command line can work, but I think most users want to use familiar user interfaces like excel to input large amounts of data. Have them export files to .csv or look into reading excel files directly with apache poi. The latter is not for beginners, but not terrible to figure out or find examples. The former should be easy to figure out if you look into reading files and splitting them line by line on the delimiter. Here's an example of that:
try (BufferedReader reader = new BufferedReader(new FileReader(new File("user_input.csv"))) {
String currentLine = reader.readLine();
while (currentLine != null) {
String splitLine[] = currentLine.split(","); //choose delimiter here
//process cells as needed
//write output somewhere so other program can read it later
currentLine = reader.readLine();
}
}
catch (IOException ex) {
System.out.println(ex.getMessage()); //maybe write to an error log
System.exit(1);
}
"input" data to other app::you can use pipes if you're at the command line. but I'd recommend you write to a file and have the other app read it. here's an expansion of the previous code snippet showing how to write to a file as that might be more practical and easier to log/archive/debug.
try (BufferedReader reader = new BufferedReader(new FileReader(new File("user_input.csv")));
BufferedWriter writer = new BufferedWriter(new FileWriter(new File("process_me.csv")))) {
String currentLine = reader.readLine();
while (currentLine != null) {
String splitLine[] = currentLine.split(","); //choose delimiter here
//process cells as needed
writer.write(processed_stuff);
currentLine = reader.readLine();
}
}
catch (IOException ex) {
System.err.println(ex.getMessage());
System.exit(1);
}
Then retrieving output::can just be reading another file with another Java program. This way you're communicating between programs using the file system. You must agree upon file formats and directories though. And you'll be limited to having both programs on the same server.
To make this at scale, you could use web services assuming the other program you're making requests to is a web service or has one wrapped around it. You can send your file and receive some response using URLConnection. This is where things will get much more complex, but now everything in your new program is just one Java program and the other code can live on another server.
Building the app first with those "intermediate" files between the user input code, the external code, and the final code will help you focus on perfecting the business logic, then you can worry about just communication over the network.
I am trying to create a Java Applet that outputs information to a text file located in the same directory as the java applet. I understand Java Applets are not ideal, but I have spent a great deal of time on this and if possible want to solve this through applets. Here is some of my code on how I could read code from a file into a text box. I assume it would be something similar to this, but outputted.
public void readFile() {
String line;
URL url = null;
try {
url = new URL(getCodeBase(), fileToRead);
}
catch(MalformedURLException e) {
}
try {
InputStream in = url.openStream();
BufferedReader bf = new BufferedReader
(new InputStreamReader(in));
strBuff = new StringBuffer();
while((line = bf.readLine()) != null){
strBuff.append(line + "\n");
}
a1.append("File Name : " + fileToRead + "\n");
a1.append(strBuff.toString());
}
catch(IOException e) {
e.printStackTrace();
}
}
If you want an applet to store data on the local machine, from 6u10 the javax.jnlp.PersistenceService is available.
or on your local machine...
java.io.File file = new java.io.File(System.getProperty("user.home"), "yourfile.txt");
You must have it signed, otherwise...
Keep in mind that from an Applet, you cannot directly write to the server's file system. You can issue a request to the server that causes the server to write to its own file system, but an Applet does not have a way to write to a file system on a remote machine.
A signed Applet has every right to write to the local file system of the person running the Applet. If you are writing to the "current directory" (rather than an absolute full path), then make sure you know what directory the Applet is running in. Otherwise you may indeed create a file, but not be able to find it!
EDIT
Signed Applet Tutorial
So what I am trying to achieve is reading the contents of a .txt file from a url:
BufferedReader reader = null;
File f = new File ("www.website.com/filename.txt");
if (f.exists()) {
try {
reader = new BufferedReader(new FileReader(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = "";
try {
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Even though I have content in the .txt file (only one line), when I print the line nothing shows up. Is reading a file from a URL or from your hard drive different, or am I doing something wrong?
The File class is for files on a "normal" file system (usually local, but potentially networked) - not URLs. Basically it's for the sort of file you can use (e.g. read or edit) directly on a command line, with no HTTP involved1.
That's what the URL class is for. So you can either use that (with URLConnection) or use a dedicated HTTP 3rd party library, such as the Apache HttpClient library.
1 I'm sure there are some shells which allow the use of URLs as if they were local filenames, but I'm talking about a more traditional approach.
I tried own my own and this worked...
URL urlObj=new URL("http://www.example.com/index.html"); //This can be any website' index.html or an available file
//we basically get HTML page/file
Scanner fGetter=new Scanner(urlObj.openStream());
while(fGetter.hasNext()){
System.out.println(""+fGetter.nextLine());
}
And I think "example.com" can be used without any legal issues :)
I don't actually know but I don't think you can read a file from a URL like that. You need to send a HTTP GET request to that url to read the information in.
See object HttpURLConnection.
http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html
I am trying to open a file i just created in my code (so i am sure that the file exists)
The code is like this:
File file = new File(filename);
file.createNewFile();
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
...
bw.close();
try {
Desktop desktop = null;
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
}
desktop.open(file);
} catch (Exception e) {
...
}
But as the title says i get a "java.io.IOException: The system cannot find the path specified" from the desktop.open(file) istruction.
The problem surely is that the file pathname contains spaces (which are translated into "%20"). Is there a way to avoid this?
I found the real problem.
It wasn't either the %20 as i supposed.
I just hadn't the privileges to directly access the file location. It's a bit complicated to explain...
i'm just sorry i coulnd't figure out the real problem before.
Thanks for your suggestions anyway!
Are you using an IDE? What is inside the variable 'filename' (it's actual contents). Line two is unnecessary.
Is the error from the stack trace pointing to BufferedWriter bw = new BufferedWriter(new FileWriter(file)); or desktop.open(file);
EDIT:
You can also try the following code
File myCSVFile; //reference to your csv file here
String execString = "excel " + myCSVFile.getAbsolutePath();
Runtime run = Runtime.getRuntime();
try {
Process pp = run.exec(execString);
} catch(Exception e) {
e.printStackTrace();
}
The java.io error is appearing because it's failing to open the file. The code above will force excel open with your file as the argument. You'll need to set your environment variable to ensure that the command 'excel' in the command line opens the Excel application.
If you're planning on releasing this application for use you can ensure that excel is installed by checking the registry, then checking the install location of Excel from there.
Try to open a different file with other applications and see if other file types are supported. As Clarisse said, IOException is thrown from the 'open' method if the specified file has no associated application or the associated application fails to be launched. If the specified file doesn't exists IllegalArgumentException is thrown, which is not in your case. If for some reason opening a CSV file with Desktop doesn't work for you, try using krslynx approach. Same can be found here. You can quickly assemble a test application for opening anything on your machine using the code found here
In the Desktop javadoc it's written :
IOException - if the specified file has no associated application or the associated application fails to be launched
So are you sure your filetype has a default application associated ?
As krslynx says, file.createNewFile() is unnecessary. However file.mkdirs() may be necessary instead, if the intermediate directories don't exist yet.
EDIT: it's not clear from your question whether this is happening in new FileWriter() or in Desktop.open(). Please clarify.
How should I load files into my Java application?
The short answer
Use one of these two methods:
Class.getResource(String)
Class.getResourceAsStream(String)
For example:
InputStream inputStream = YourClass.class.getResourceAsStream("image.jpg");
--
The long answer
Typically, one would not want to load files using absolute paths. For example, don’t do this if you can help it:
File file = new File("C:\\Users\\Joe\\image.jpg");
This technique is not recommended for at least two reasons. First, it creates a dependency on a particular operating system, which prevents the application from easily moving to another operating system. One of Java’s main benefits is the ability to run the same bytecode on many different platforms. Using an absolute path like this makes the code much less portable.
Second, depending on the relative location of the file, this technique might create an external dependency and limit the application’s mobility. If the file exists outside the application’s current directory, this creates an external dependency and one would have to be aware of the dependency in order to move the application to another machine (error prone).
Instead, use the getResource() methods in the Class class. This makes the application much more portable. It can be moved to different platforms, machines, or directories and still function correctly.
getResource is fine, but using relative paths will work just as well too, as long as you can control where your working directory is (which you usually can).
Furthermore the platform dependence regarding the separator character can be gotten around using File.separator, File.separatorChar, or System.getProperty("file.separator").
What are you loading the files for - configuration or data (like an input file) or as a resource?
If as a resource, follow the suggestion and example given by Will and Justin
If configuration, then you can use a ResourceBundle or Spring (if your configuration is more complex).
If you need to read a file in order to process the data inside, this code snippet may help BufferedReader file = new BufferedReader(new FileReader(filename)) and then read each line of the file using file.readLine(); Don't forget to close the file.
I haven't had a problem just using Unix-style path separators, even on Windows (though it is good practice to check File.separatorChar).
The technique of using ClassLoader.getResource() is best for read-only resources that are going to be loaded from JAR files. Sometimes, you can programmatically determine the application directory, which is useful for admin-configurable files or server applications. (Of course, user-editable files should be stored somewhere in the System.getProperty("user.home") directory.)
public byte[] loadBinaryFile (String name) {
try {
DataInputStream dis = new DataInputStream(new FileInputStream(name));
byte[] theBytes = new byte[dis.available()];
dis.read(theBytes, 0, dis.available());
dis.close();
return theBytes;
} catch (IOException ex) {
}
return null;
} // ()
use docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#getResource(java.lang.String)
public static String loadTextFile(File f) {
try {
BufferedReader r = new BufferedReader(new FileReader(f));
StringWriter w = new StringWriter();
try {
String line = reader.readLine();
while (null != line) {
w.append(line).append("\n");
line = r.readLine();
}
return w.toString();
} finally {
r.close();
w.close();
}
} catch (Exception ex) {
ex.printStackTrace();
return "";
}
}