I currently have the follow method:
try {
URL url = new URL("http://auth.h.gp/HAKUNA%20MATATA.txt");
Scanner s = new Scanner(url.openStream());
}
catch(IOException ex) {
BotScript.log("Something went wrong =/ Error code:");
ex.printStackTrace();
stop();
}
However, how do I check if it contains a word? I've never worked with Scanners before and I found this snippet online.
Thank you.
Okay, that looks good so far.
You can then use Scanner's next() method to get each word. You can also query hasNext() to see if there's another token available to avoid errors.
boolean foundPumbaa = false;
while (s.hasNext()) {
if (s.next().equalsIgnoreCase("pumbaa")) {
foundPumbaa = true;
System.out.println("We found Pumbaa"); // do something
break;
}
}
if (!foundPumbaa) {
System.out.println("We didn't find Pumbaa");
}
EDIT in response to comment:
Yes, you can turn the text into a String. The best way to do this is probably with a BufferedReader.
From the Java Tutorial, "Reading Directly from a URL":
The following small Java program uses openStream() to get an input
stream on the URL http://www.oracle.com/. It then opens a
BufferedReader on the input stream and reads from the BufferedReader
thereby reading from the URL. Everything read is copied to the
standard output stream:
import java.net.*;
import java.io.*;
public class URLReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("http://www.oracle.com/");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
In a real program, instead of main throws Exception, you'd have that in a try-catch block and catch an IOException and some various URLExceptions. But this should get you started.
Related
I'm writing a mock stock market in Java, and I want the ability for the user to view stocks purchased. I decided the easiest way to do this is to write to a file. My problem is that every time I run this program and attempt to read from the file, it outputs the path it took to read it. The information I want is correctly written to the file, but it isn't reading from it the way I want.
Here is the code I used for the file reading section:
if (amountOfStocks1 >= 1) {
Scanner stocksBought1 = new Scanner("stocksbought/stocksBought1.txt");
while (stocksBought1.hasNext()) {
String fileRead = stocksBought1.nextLine();
System.out.println(fileRead);
}
stocksBought1.close();
runMenu = 1;
}
There are 7 of these amountOfStocks if/else statements.
I'm not sure if that's enough information. If it's not, tell me what to put on, and I'll do that.
If you can help me fix this problem or if you know an easier way to read and write to files that would be great!
Instead of:
Scanner stocksBought1 = new Scanner("stocksbought/stocksBought1.txt");
Try:
Scanner stocksBought1 = new Scanner(new File("stocksbought/stocksBought1.txt"));
When you only pass a String to the Scanner constructor the Scanner just scans that String. If you give it a File it will scan the contents of the File.
You would probably be better off using the FileReader object. You would use code similar to the following:
import java.io.*;
class FileReaderDemo {
public static void main(String args[]) throws Exception
{
FileReader fr = new FileReader("FileReaderDemo.java");
BufferedReader br = new BufferedReader(fr);
String s;
while((s = br.readLine()) != null) {
System.out.println(s);
}
fr.close();
}
}
In addition, you can use the FileWriter object to write to a file. There's lots of examples on the internet. Easy to find on simple Google search. Hope this helps.
Use FileReader.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderExample {
public static void main(String[] args) {
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader("C:\\testing.txt"));
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
If I have something like this in my code:
String line = r.readLine(); //Where r is a bufferedReader
How can I avoid a crash if the next line is the end of the file? (i.e. null)
I need to read the next line because there may be something there that I need to deal with but if there isn't the code just crashes.
If there is something there then all is OK, but I can't be guaranteed that there will be something there.
So if I do something like: (pseudo code):
if (r.readLine is null)
//End code
else {check line again and excecute code depending on what the next line is}
The issue I have with something like this is, that when I check the line against null, it already moves onto the next line, so how can I check it again?
I've not worked out a way to do this - any suggestions would be a great help.
Am... You can simply use such a construction:
String line;
while ((line = r.readLine()) != null) {
// do your stuff...
}
If you want loop through all lines use that:
while((line=br.readLine())!=null){
System.out.println(line);
}
br.close();
You can use the following to check for the end of file.
public bool isEOF(BufferedReader br)
{
boolean result;
try
{
result = br.ready();
}
catch (IOException e)
{
System.err.println(e);
}
return result;
}
In your case you can read the next line because there may be something there.If there isn't anything, your code won't crash.
String line = r.readLine();
while(line!=null){
System.out.println(line);
line = r.readLine();
}
A question in the first place, why don't you use "Functional Programming Approach"? Anyways, A new method lines() has been added since Java 1.8, it lets BufferedReader returns content as Stream. It gets all the lines from the file as a stream, then you can sort the string based on your logic and then collect the same in a list/set and write to the output file. If you use the same approach, there is no need to get worried about NullPointerException. Below is the code snippet for the same:-
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Collectors;
public class LineOperation {
public static void main(String[] args) throws IOException {
Files.newBufferedReader(Paths.get("C://xyz.txt")).
lines().
collect(Collectors.toSet()). // You can also use list or any other Collection
forEach(System.out::println);
}
}
You can do it via BufferReader. I know this is not relevant to following question. But I would post it for extra fact for a newbie who would not use BufferReader but Scanner for reading file.
A part from BufferReader you could use Java Scanner class to read the file and check the last line.
Buffer Reader
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// process the line
}
}
Scanner
try {
Scanner scanner = new Scanner(new FileReader(file));
while (scanner.hasNext()) {
// Above checks whether it has or not ....
}
} catch (IOException e) {
e.printStackTrace();
}
If you use this code fragment in a multi threaded environment, go ahead with BufferReader since its synchronized.
In addition, BufferReader is faster than Scanner.
If you would like to do some check like:
if (reader.ready())
stringBuilder.append("#");
You can use ready()
public static void check() throws IOException {
InputStream in = new FileInputStream(new File(filePath));
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
if (reader.ready())
stringBuilder.append("#");
}
String returnedString = stringBuilder.toString();
System.out.println(returnedString);
}
You could purposely have it throw the error inside your loop. i.e.:
String s = "";
while (true) {
try {
s = r.readline();
}catch(NullPointerException e) {
r.close();
break;
}
//Do stuff with line
}
what everyone else has sad should also work.
I am running a client and servlet under jetty locally. When I read the message in the client, I do:
in = new Scanner(conn.getInputStream());
StringBuffer messageBuffer = new StringBuffer();
while (in.hasNext()) {
messageBuffer.append(in.next()).append(" ");
}
and I expect that when there is no data coming from the servlet, it should freeze at
while (in.hasNext())
instead, I just end up with empty messageBuffer, and i have to deal with it and call the method again and again until I get a message. Why is this happening? How can I make it stop at the while statement and wait until there is data coming in?
Here is how the url connection is started(once, in client constructor):
try {
url = new URL("http://localhost:8182/stream");
conn = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException ioE) {
ioE.printStackTrace();
}
from the Scanner doc:
The next() and hasNext() methods and their primitive-type companion
methods (such as nextInt() and hasNextInt()) first skip any input that
matches the delimiter pattern, and then attempt to return the next
token. Both hasNext and next methods may block waiting for further
input. Whether a hasNext method blocks has no connection to whether or
not its associated next method will block.
it says that it might block, but it is not part of the api, it depends on the underline implementation according to what you scan.
anyway, you need to implement the wait yourself by something like:
while (!in.hasNext() && !stop){
sleep();
}
The javadoc states that Scanner.hasNext() and Scanner.next() may block. It really depends on the underlying InputStream. I personally wouldn't ever use a Scanner to read from a socket if that's what that is.
A more sane approach is probably to use an an InputStreamReader wrapped by a BufferedReader. Also worth mentioning is that you should be using StringBuilder rather than StringBuffer unless you need thread safety.
BufferedReader br =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String input = null;
while ((input = br.readLine()) != null)
{
sb.append(input).append(" ");
}
Note this is using readLine() which may or may not suit your needs depending on what you're receiving. It also assumes the other end of the connection is going to close when it's done sending. You may want to use one of the read() methods instead and parse accordingly.
Edit to add from comments below: This is literally how blocking reads work in Java. Here's a complete example:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class App
{
public static void main( String[] args ) throws MalformedURLException, IOException
{
URL url = new URL("http://www.google.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
BufferedReader br =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String input = null;
while ((input = br.readLine()) != null)
{
sb.append(input).append(" ");
}
System.out.println(sb.toString());
}
}
Output (cut off for brevity here, but it's the entire page):
<!doctype html><html itemscope="itemscope" itemtype="http://schema.org/WebPage"><head> ...
In my experience, I have always tried to avoid blocking and therefore have avoided using Scanner methods for hasNext().
Instead, I have used the InputStream. InputStream, which you have used in the code:
conn.getInputStream();
You can then use the InputStream method available() to see if any information has passed through.
So for your code, I would recommend:
InputStream inStream = conn.getInputStream();
in = new Scanner(inStream);
StringBuffer messageBuffer = new StringBuffer();
while (in.available() <= 0)
{
try{
Thread.sleep(100);
}
catch(InterruptedException e){}
}
messageBuffer.append(in.next()).append(" ");
Edited :
try using for loop instead of while loop, where the range will be from 0 to (length -1). you will have to find length using while(in.hasNextLine()) and put length counter inside it .Dont forget to close the scanner after you are done with filling the messageBuffer (using .close()). just try it out. It should work.
import java.io.*;
import java.util.*;
public class Readfilm {
public static void main(String[] args) throws IOException {
ArrayList films = new ArrayList();
File file = new File("filmList.txt");
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNext())
{
String filmName = scanner.next();
System.out.println(filmName);
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}}
Above is the code I'm currently attempting to use, it compiles fine, then I get a runtime error of:
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1416)
at Readfilm.main(Readfilm.java:15)
I've googled the error and not had anything that helped (I only googled the first 3 lines of the error)
Basically, the program I'm writing is part of a bigger program. This part is to get information from a text file which is written like this:
Film one / 1.5
Film two / 1.3
Film Three / 2.1
Film Four / 4.0
with the text being the film title, and the float being the duration of the film (which will have 20 minutes added to it (For adverts) and then will be rounded up to the nearest int)
Moving on, the program is then to put the information in an array so it can be accessed & modified easily from the program, and then written back to the file.
My issues are:
I get a run time error currently, not a clue how to fix? (at the moment I'm just trying to read each line, and store it in an array, as a base to the rest of the program) Can anyone point me in the right direction?
I have no idea how to have a split at "/" I think it's something like .split("/")?
Any help would be greatly appreciated!
Zack.
Your code is working but it reads just one line .You can use bufferedReader here is an example import java.io.*;
class FileRead
{
public static void main(String args[])
{
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("textfile.txt");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
And here is an split example class StringSplitExample {
public static void main(String[] args) {
String st = "Hello_World";
String str[] = st.split("_");
for (int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
}
}
I wouldn't use a Scanner, that's for tokenizing (you get one word or symbol at a time). You probably just want to use a BufferedReader which has a readLine method, then use line.split("/") as you suggest to split it into two parts.
Lazy solution :
Scanner scan = ..;
scan.nextLine();
I am trying to read some words from an online text file.
I tried doing something like this
File file = new File("http://www.puzzlers.org/pub/wordlists/pocket.txt");
Scanner scan = new Scanner(file);
but it didn't work, I am getting
http://www.puzzlers.org/pub/wordlists/pocket.txt
as the output and I just want to get all the words.
I know they taught me this back in the day but I don't remember exactly how to do it now, any help is greatly appreciated.
Use an URL instead of File for any access that is not on your local computer.
URL url = new URL("http://www.puzzlers.org/pub/wordlists/pocket.txt");
Scanner s = new Scanner(url.openStream());
Actually, URL is even more generally useful, also for local access (use a file: URL), jar files, and about everything that one can retrieve somehow.
The way above interprets the file in your platforms default encoding. If you want to use the encoding indicated by the server instead, you have to use a URLConnection and parse it's content type, like indicated in the answers to this question.
About your Error, make sure your file compiles without any errors - you need to handle the exceptions. Click the red messages given by your IDE, it should show you a recommendation how to fix it. Do not start a program which does not compile (even if the IDE allows this).
Here with some sample exception-handling:
try {
URL url = new URL("http://www.puzzlers.org/pub/wordlists/pocket.txt");
Scanner s = new Scanner(url.openStream());
// read from your scanner
}
catch(IOException ex) {
// there was some connection problem, or the file did not exist on the server,
// or your URL was not in the right format.
// think about what to do now, and put it here.
ex.printStackTrace(); // for now, simply output it.
}
try something like this
URL u = new URL("http://www.puzzlers.org/pub/wordlists/pocket.txt");
InputStream in = u.openStream();
Then use it as any plain old input stream
What really worked to me: (source: oracle documentation "reading url")
import java.net.*;
import java.io.*;
public class UrlTextfile {
public static void main(String[] args) throws Exception {
URL oracle = new URL("http://yoursite.com/yourfile.txt");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
Using Apache Commons IO:
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public static String readURLToString(String url) throws IOException
{
try (InputStream inputStream = new URL(url).openStream())
{
return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}
}
Use this code to read an Internet resource into a String:
public static String readToString(String targetURL) throws IOException
{
URL url = new URL(targetURL);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(url.openStream()));
StringBuilder stringBuilder = new StringBuilder();
String inputLine;
while ((inputLine = bufferedReader.readLine()) != null)
{
stringBuilder.append(inputLine);
stringBuilder.append(System.lineSeparator());
}
bufferedReader.close();
return stringBuilder.toString().trim();
}
This is based on here.
For an old school input stream, use this code:
InputStream in = new URL("http://google.com/").openConnection().getInputStream();
I did that in the following way for an image, you should be able to do it for text using similar steps.
// folder & name of image on PC
File fileObj = new File("C:\\Displayable\\imgcopy.jpg");
Boolean testB = fileObj.createNewFile();
System.out.println("Test this file eeeeeeeeeeeeeeeeeeee "+testB);
// image on server
URL url = new URL("http://localhost:8181/POPTEST2/imgone.jpg");
InputStream webIS = url.openStream();
FileOutputStream fo = new FileOutputStream(fileObj);
int c = 0;
do {
c = webIS.read();
System.out.println("==============> " + c);
if (c !=-1) {
fo.write((byte) c);
}
} while(c != -1);
webIS.close();
fo.close();
Alternatively, you can use Guava's Resources object:
URL url = new URL("http://www.puzzlers.org/pub/wordlists/pocket.txt");
List<String> lines = Resources.readLines(url, Charsets.UTF_8);
lines.forEach(System.out::println);
corrected method is deprecated now. It is giving the option
private WeakReference<MyActivity> activityReference;
here solution will useful.