My goal here is to read lines from a text file, check if they are palindromes, and then write those to a completely different file.
Now the problem, as far as I can see, lies in the if statement block where I check for palindromes successfully but can't seem to write them to another file because they are stored in a variable.
When I use the BufferedWriter write method and set the parameters as an actual string with quotes, everything works.
How can I solve this?
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
public class Zadatak14 {
public static void main(String[] args) {
BufferedReader br;
try {
br = new BufferedReader(new FileReader("C:\\Users\\Luka\\Documents\\NetBeansProjects\\CS101-DZ14-14\\src\\zadatak14\\ulaz.txt"));
String line;
while ((line = br.readLine()) != null) {
String palindrome = new StringBuilder(line).reverse().toString();
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Luka\\Documents\\NetBeansProjects\\CS101-DZ14-14\\izlaz.txt"));
if (line.contains(palindrome)) {
System.out.println(line);
bw.write(line);
}
bw.close();
}
br.close();
} catch (FileNotFoundException e) {
System.out.println("Greska");
} catch (IOException ex) {
System.out.println("Greska");
}
}
}
BufferedWriter bw = new BufferedWriter
You're making a new writer for every line in your input, which surely you don't want. Move the creation of the writer up top, right after opening the reader.
br.close();
not how you do that. This is how you do that:
try (BufferedWriter bw = new BufferedWriter(new FileWriter("...."))) {
// code here
}
// no matter how you get out of this code, the file is closed.
The reason you do it with the above is because that bw.close() won't get called if exceptions occur, if you return out of the block. With the try construct, that stream is closed when code exits from the block no matter how it does that.
} catch (FileNotFoundException e) {
System.out.println("Greska");
Not how you do that - exceptions contain a lot of useful info (at least 4 things, more for some specific kinds of exceptions: type, message, stack trace, cause), and you're tossing it all in the garbage. It's a bad idea to toss information about problems in the bin. Don't. The right move is to add throws Exception to your public static void main(String[] args) method, and then you don't need a catch at all. If you must, the correct body for a catch block if you don't have a good way to handle the problem, is throw new RuntimeException("Uncaught", e);. This preserves all information and doesn't cause errors about having to catch exceptions.
Related
Let me explain the situation. In Windows OS.
My java program writes the logfile.
Usually It's OK, but when I copying and pasting the logfile(ctrl + c and v),
java throws exception java.io.IOException: java.io.FileNotFoundException: C:\log.txt (The process cannot access the file because it is being used by another process)
After I research the problem, I found this exception throws by pasting the file. Not copying.
Please tell me why this exception occur.
Reproduce code is below(encode "Windows-31J" is japanese, there is no
particular meaning). Excecute this program and copy and paste "C:\log.txt".
package test;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.stream.IntStream;
public class FileNotFound {
public static void main(String[] args) {
IntStream.range(0, 100000).parallel().forEach(
i -> {
try {
fileWrite("C:\\log.txt", String.valueOf(i));
} catch (IOException e) {
e.printStackTrace();
}
}
);
}
public static void fileWrite(String filePath, String str) throws IOException {
try (FileOutputStream fw = new FileOutputStream(filePath, true);
OutputStreamWriter ow = new OutputStreamWriter(fw, "Windows-31J");
BufferedWriter bw = new BufferedWriter(ow);
PrintWriter out = new PrintWriter(bw)) {
out.println(str);
} catch (IOException e) {
throw new IOException(e);
}
}
}
It occurs because another process, i.e. your Explorer window, is using the file, via the 'copy' action, which Windows does not allow. Solution: don't.
The following code has I/O authority in my local PC and runs correctly. However when I've tried to do this on my windows server2012, some problems occured. It can't run python code correctly by using exec, my python cannot give the final result. I think it has no authority to I/O, but why?
Java code:
package test;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class test {
private static void generateFile() throws IOException{
BufferedWriter bw = new BufferedWriter(new FileWriter("src/test/input.txt", false));
String eventString = "This is a example";
bw.write(eventString);
bw.close();
}
private static void getFile() throws IOException{
BufferedReader br = new BufferedReader(new FileReader("src/test/output.txt"));
String jsonResults = br.readLine();
br.close();
}
public static void main(String[] args) throws IOException {
generateFile();
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("python test.py", null, new File("src/test/"));
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
try {
pr.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
pr.destroy();
}
getFile();
}
}
python code:
f = open('input.txt', 'r')
line = f.readline()
with open('output.txt', 'w') as fw:
fw.write(line)
print("Done!")
ERROR infomation :
Exception in thread "main" java.io.FileNotFoundException: src\test\output.txt (The system cannot find the specified file.)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at java.io.FileReader.<init>(FileReader.java:58)
at test.test.getFile(test.java:21)
at test.test.main(test.java:49)
Various things here (for the moment more "code quality" hints):
Your poor method is doing way too many things. Example:
Individual "parts", like the following - should all go into a simple helper methods:
String eventString = getJsonEventListInTopic(topicLabel);
FileWriter fw = ...
fw.close();
Meaning: you want to read about the Single Layer Of Abstraction principle
The core point to make progress on your actual question: when you run your python script manually on that windows system (with exactly the same arguments/parameters) on the command line - does that work? You know, it could be something super-simple as "python.exe is not in your path"
I am writing a program in which I want to start a shell in the background, and send and receive the input and output. I already have managed to do this, and can successfully read and write to this process. This is where I run into trouble.
I would like to have a method in ShellManager (see below code) that waits until whatever the process is doing finishes/fails, and returns input to the user.
For example, if I send tar xzf something_that_will_take_a_while.tar.gz,
I can see in the output how it takes its time, and then echoes this:
]0;~
[32mMe#MyComputer [33m~[0m
I already tried blocking the thread until ]0;~ was received, this did not work. (Never returned)
I also tried \u001B, same problem :(
I'm not sure what the symbol is, and can't find much on how to detect when the process returns.
Here is my code:
package buildSystem.shell;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import base.TermConstants;
public class ShellManager {
private InputStream termOut;
private OutputStream termIn;
private ProcessBuilder build;
private Process main;
BufferedReader reader;
BufferedWriter writer;
public ShellManager() {
build = new ProcessBuilder(TermConstants.getShellLocation());
build.redirectErrorStream(true);
}
public void start() throws IOException {
try {
main = build.start();
termOut = main.getInputStream();
termIn = main.getOutputStream();
reader = new BufferedReader (new InputStreamReader(termOut));
writer = new BufferedWriter(new OutputStreamWriter(termIn));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void writeLine(String s) throws IOException {
writer.write(s);
writer.newLine();
writer.flush();
}
public String readNextLine() throws IOException {
return reader.readLine();
}
public void end() {
try {
writeLine("exit\n");
main.waitFor();
termOut.close();
termIn.close();
reader.close();
writer.close();
} catch (IOException | InterruptedException e) {
kill();
}
}
public void kill() {
main.destroyForcibly();
try {
termOut.close();
termIn.close();
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*THE PART I AM HAVING TROUBLE WITH:*/
public void waitForReturn() {
try {
while(reader.readLine() != "\u001B") {}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Basically, I want a reliable way to detect when a program exits from a bash shell. The bash process will still be running, but the program running from that bash instance will have returned. Because of this I cannot use process.waitFor().
I tried waiting for ]0;~, and then the [32mMe#MyComputer [33m~[0m, which worked until an tar exited with an error code, in which case the two lines would be reversed. I am unsure how to proceed, as detecting that bash has returned to the user should be a relatively easy task.
Thanks for your help!
If this represents the way you have been trying to match output, it's your problem:
while(reader.readLine() != "\u001B") {}
Except in special cases, you have to use the equals() method on String instances:
while (true) {
String line = reader.readLine();
if ((line == null) || "\u001B".equals(line))
break;
}
I'm not sure why you expect ESC and a newline when a process exits though.
I believe you need to call the Process.waitFor() method.
So you need something like:
Process p = build.start();
p.waitFor()
If you are trying to simulate a bash shell, allowing input of a command, executing, and processing output without terminating. There is an open source project that may be a good reference for code on how to do this. It is available on Git. Take a look at the Jediterm Pure Java Emulator.
Thinking about simulating a bash, I also found this example for Piping between processes also be be relevant.
It does show how to extract the output of a process executing and piping that data as the input into another Java Process. Should be helpful.
I have this code below. Basically I'm getting an input from a given url. This website shows a sentence. Each time I reload the website it gets a new sentence and so on. So, I managed to get that working. Now I'm trying to write the sentence in a textfile. But something is wrong. It only writes the first line and nothing else. What's wrong with my code?
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class ReadIp {
public static void main(String[] args) throws MalformedURLException, IOException,
InterruptedException {
ReadIp readIP = new ReadIp();
while (true) {
readIP.getIP();
Thread.sleep(2000);
}
}
BufferedReader buff;
InputStreamReader inStream;
String line;
URL url;
URLConnection urlConn;
FileWriter fileWriter ;
BufferedWriter bufferedWriter;
public ReadIp() throws IOException {
fileWriter = new FileWriter("myfile.txt", true);
bufferedWriter = new BufferedWriter(fileWriter);
}
public void getIP() throws MalformedURLException, IOException {
this.url = new URL("http://test.myrywebsite.co.uk");
this.urlConn = this.url.openConnection();
this.inStream = new InputStreamReader(this.urlConn.getInputStream());
this.buff = new BufferedReader(this.inStream);
try {
while ((this.line = this.buff.readLine()) != null)
{
System.out.println(this.line);
try {
this.bufferedWriter.write(this.line);
this.bufferedWriter.write("\n");
this.bufferedWriter.flush();
} catch (IOException e)
{
}
}
if (this.bufferedWriter != null)
{
this.bufferedWriter.close();
}
this.inStream.close();
}
catch (Exception ex)
{
}
}
}
Any help would be greatly appreciated.
Thank you.
Move the statement
writer.close();
out of the inner try catch block so that you're not closing the OutputStream after writing the first entry to the file. The same applys to the InputStream
inStream.close();
The BufferedWriter is being opened in the constructor and is being closed in getIp. The constructor is called only once, but getIp is called every 2 seconds to read a sentence. So the BufferedWriter is being closed after the first line (and not opened again). The second call of getIp tries to write the second sentence but the BufferedWriter is closed. This should throw an Exception which is being ignored since the catch block is empty.
Never leave a catch block empty - as fgb wrote above!
First of all, at least add a printStackTrace() to each empty catch block, e.g.:
catch (Exception ex) {
ex.printStackTrace();
}
so you can see if an Exception is being thrown...
I would suggest to open the BufferedWriter in the method getIp instead of the constructor; or, if it should stay open all the time, close the BufferedWriter in an additional method, called after the loop in main terminates
I've been trying to come up with a class that deletes a line from a text file that starts with a particular number.
What I currently have doesn't show any code errors and also runs without erros; shows "BUILD SUCCESSFUL" on netbeans, but doesn't do anything to the line, or any part of the textfile whatsoever, let alone delete the intended line.
Could anyone please look at my code and please advise me on what I might have done wrong, or is missing?
Thanks a lot in advance.
Heres my code:
package Database;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class Edit {
public void removeLineFromFile(String file, String lineToRemove) {
try {
File inFile = new File("/D:/TestFile.txt/");
if (!inFile.isFile()) {
System.out.println("Parameter is not an existing file");
return;
}
//Construct the new file that will later be renamed to the original filename.
File tempFile = new File(inFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
String line = null;
//Read from the original file and write to the new
//unless content matches data to be removed.
while ((line = br.readLine()) != null) {
if (!line.trim().equals(line.startsWith(lineToRemove))) {
pw.println(line);
pw.flush();
}
}
pw.close();
br.close();
//Delete the original file
if (!inFile.delete()) {
System.out.println("Could not delete file");
return;
}
//Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile))
System.out.println("Could not rename file");
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
Edit edit = new Edit();
edit.removeLineFromFile("/D:/TestFile.txt/", "2013001");
}
}
There is a problem with your logic ... you are saying if the line equals to itself that starts with something which will never happen unless the line only consist of the line you want to remove
if (!line.trim().equals(line.startsWith(lineToRemove))
i think needs to be just
if (!line.startsWith(lineToRemove))
Change the if condition to:
if (!line.startsWith(lineToRemove)) {
pw.println(line);
pw.flush();
}