So I have this task to do, I need to expand text abbreviations from the message into their full form from the .csv file, I loaded that file into HashMap, with keys as abbreviations and values as full forms. There is a loop to iterate through the keys and if statement which replaces abbreviation to full form if it finds any. I kind of figured it out and it is working as it should but I want to send this changed String (with abbreviations expanded) somewhere else out of if statement to save the full message to the file. I know that this String exists only in this if statement but maybe there is another way of doing it? Or maybe I'm doing something wrong? I became a bit rusty with Java so maybe there is a simple explanation that I don't know about. Here is the code I have :
public class AbbreviationExpander {
static void AbrExpander(String messageBody) {
//read the .csv file
String csvFile = "textwords.csv";
String line = "";
String cvsSplitBy = ",";
String bodyOut = messageBody;
HashMap<String, String> list = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) != null) {
String[] abbreviatonFile = line.split(cvsSplitBy);
//load the read data into the hashmap
list.put(abbreviatonFile[0], abbreviatonFile[1]);
}
for (String key : list.keySet()) {
//if any abbreviations found then replace them with expanded version
if (messageBody.contains(key)) {
bodyOut = bodyOut.replace(key, key + "<" + list.get(key).toLowerCase() + ">");
try {
File file = new File("SMS message" + System.currentTimeMillis() + ".txt");
FileWriter myWriter = new FileWriter(file);
myWriter.write(bodyOut);
myWriter.close();
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}
} catch (IOException f) {
f.printStackTrace();
}
}
}
Not sure I understood well your problem. But I think you should separate the different steps in your code.
I mean your try-catch block that writes your output should be outside the for-loop and outside the reading try-catch. And your for-loop should be outside your reading try-catch.
public class AbbreviationExpander {
static void AbrExpander(String messageBody) {
String csvFile = "textwords.csv";
String line = "";
String cvsSplitBy = ",";
String bodyOut = messageBody;
HashMap<String, String> list = new HashMap<>();
//read the .csv file
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) != null) {
String[] abbreviatonFile = line.split(cvsSplitBy);
//load the read data into the hashmap
list.put(abbreviatonFile[0], abbreviatonFile[1]);
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
//if any abbreviations found then replace them with expanded version
for (String key : list.keySet()) {
if (messageBody.contains(key)) {
bodyOut = bodyOut.replace(key, key + "<" + list.get(key).toLowerCase() + ">");
}
}
//output the result in your file
try {
File file = new File("SMS message" + System.currentTimeMillis() + ".txt");
FileWriter myWriter = new FileWriter(file);
myWriter.write(bodyOut);
myWriter.close();
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
}
Related
I have tried to get string and numeric values from a text file using BufferedReader. Apparently, it is recognizing the number of records (lines) of the text file, but the values are not being retrieved as they are. String ones are being placed as "null" and double as zeros. I am kind of new in Java and I would like to know the possible reason of this output and also how could I solve it.
I tried to adapt the results to an arraylist as part of a table visualization, however after some tries it was not possible solve the problem:
private ArrayList<ListClasses> seeListe() {
ArrayList<ListClasses> list = new ArrayList<>();
File file = new File("C:/file/to/path/file.txt");
BufferedReader br = null;
try {
FileReader fr = new FileReader(file);
BufferedReader breader = new BufferedReader(fr);
String line = breader.readLine();
while (line != null) {
list.add(new ListClasses());
line = breader.readLine();
}
} catch (FileNotFoundException e) {
System.out.println("File not found: " + file.toString());
} catch (IOException e) {
System.out.println("Unable to read file: " + file.toString());
}
finally {
try {
br.close();
} catch (IOException e) {
System.out.println("Unable to close file: " + file.toString());
}
catch(NullPointerException ex) {
}
}
return list;
}
The records in you file should really represent one object so your class name shouldn't be a plural, but if your ctor is right, you can just do:
List<ListClasses> data = Files.lines(Paths.get(pathToDataFile)).map(ListClasses::new).collect(Collectors.toList());
When I am writing text in this txt file, there either is no space between the new string and the old existing string, or there is extra lines, which messes up my other algorithms.
public String writeStudent(String file, String name)
{
String txt = "";
//set through put method
try(FileWriter fw = new FileWriter(file + ".txt", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw))
{
out.println(name + "\r\n");
//save userinput into class1.txt
txt ="added: " + name;
}
catch(IOException e)
{
System.out.println("error");
e.printStackTrace();
// detact error
}
return txt;
}
This is the code I am using to writing in txt, using (name + "\r\n") gives me extra empty lines.
How about use BufferedWriter instead of PrintWriter?
It's my sample code. please try test below code.
import java.io.*;
public class Stackoverflow {
public static void main(String[] args) {
File file = new File("C:\\test.txt");
OutputStream outputStream = null;
Writer writer = null;
BufferedWriter bufferedWriter = null;
try {
outputStream = new FileOutputStream(file);
writer = new OutputStreamWriter(outputStream);
bufferedWriter = new BufferedWriter(writer);
bufferedWriter.write("Hello");
bufferedWriter.write("\r\n");
bufferedWriter.write("\r\n");
bufferedWriter.write("Bye");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bufferedWriter != null) {
try {
bufferedWriter.close();
} catch (Exception ignore) {
}
}
if (writer != null) {
try {
writer.close();
} catch (Exception ignore) {
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (Exception ignore) {
}
}
}
}
}
output
Hello
Bye
The problem is the println function automatically adds new line at end of input string.
out.println(name + "\r\n"); Is effectively the same as out.print(name + "\r\n\r\n");
Lastly you need to think about if new line needs to be before or after your student name.
The solution is to simply use print instead of println and add a new line before the student name
For example.
Given existing text file
John Doe
and you want a new name to be added as
John Doe
Jane Doe
The newline is actually before your name input. Meaning you should use something like out.print("\r\n" + name);
I'm working on a project where I have a file that the program accesses to get information on different crimes from a range of years. It then needs to add up the crime based on the type and put it into a file. I have the first part down, it does access the file and adds up the crime amounts by type but when I open the file that is created, it's not printing out correctly and I can't seem to find what's wrong.
This is what prints out on the file:
¬í sr java.util.HashMapÚÁÃ`Ñ F
loadFactorI thresholdxp?# w
t Violent Crimes Totalsr java.lang.Integerâ ¤÷‡8 I valuexr java.lang.Number†¬•”à‹ xp ¤Mt Rapesq ~ jt
Vehicle Theftsq ~ {™t Aggravated Assaultsq ~ kƒt Homicidesq ~ t Robberysq ~ N
t NonResidential Burglarysq ~ kÿt Residential Burglarysq ~ ã~t Property Crimes Totalsq ~ ïit Theftsq ~ :cx
With the system.out.println it prints:
{Violent Crimes Total=42061, Rape=1898, Vehicle Theft=97177, Aggravated Assault=27523, Homicide=399, Robbery=19981, NonResidential Burglary=27647, Residential Burglary=58238, Property Crimes Total=454505, Theft=342627}
The system print out is what I'd like to show up in the file.
public class CSVReader {
public static void main(String[] args) throws FileNotFoundException {
String csvFile = "C:\\Users\\Cassie\\Desktop\\mod04_dataset.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
HashMap<String, Integer> map = new HashMap<>();
try {
br = new BufferedReader(new FileReader(csvFile));
br.readLine();
while ((line = br.readLine()) != null) {
String[] data = line.split(cvsSplitBy);
System.out.println(data[2] + " " + data[3]);
if (map.containsKey(data[2])) {
Integer a = map.get(data[2]);
map.put(data[2], a + Integer.parseInt(data[3]));
}
else {
map.put(data[2], Integer.parseInt(data[3]));
}
}
FileOutputStream f = new
FileOutputStream("hashmap.ser");
ObjectOutputStream s = new ObjectOutputStream(f);
s.writeObject(map);
System.out.println(map);
s.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
When you call System.out.println(map);, you see the result of map.toString(). If this is what you want to have in the file, you can do it like this :
FileOutputStream f = new FileOutputStream("hashmap.ser");
f.write(map.toString().getBytes());
System.out.println(map);
f.close();
You should use PrintWriter, cause nö you are outputting a binary Data
I'm implementing a small tool in Java. I have a excel document and from every sheet I need to generate a .sql file. I've created an sql file model, which I have to read from for every excel sheet then replace a value and write it back to another .sql file. The problem is I use a for where I loop through my sheets and for every sheet I need to read that sql file, modify it and export it somewhere else. I get a "Stream closed" error, and I don't know how to close my buffer and/or my InputStream properly. Can you guys help me out with this ?
This is my code:
This gets everything from the file and converts it to a String
public String getString(InputStream is) throws IOException {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
String line;
try {
reader = new BufferedReader(new InputStreamReader(is));
while ((line = reader.readLine()) != null) {
sb.append(line + System.lineSeparator());
}
} catch (IOException ex) {
ex.printStackTrace();
}
return sb.toString();
}
This is used to export the file
public void exportFile(String text, String path, String name, String extension) {
BufferedWriter output = null;
try {
File sqlFile = new File(path + name + extension);
output = new BufferedWriter(new FileWriter(sqlFile));
output.write(text);
} catch (IOException e) {
e.printStackTrace();
logger.severe("Unable to write to file!\n");
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
logger.severe("Unable to close buffer\n");
}
}
}
}
And this a the part of my run() method, which uses the code above:
ClassLoader loader = this.getClass().getClassLoader();
InputStream createTableInputStream = loader.getResourceAsStream("val_table_create.sql");
if (createTableInputStream == null) {
logger.severe("No tempalte found for creating table!\n");
return;
}
List<Sheet> bookSheets = getSheets(book);
for (Sheet sheet : bookSheets) {
setHeader(table, sheet);
String exportText = getString(createTableInputStream);
exportText = exportText.replaceAll(TABLE_NAME, tableName);
// exportText = exportText.replaceAll(VAL_DATA_TYPE, valDataType);
// exportText = exportText.replaceAll(MSG_TEXT_DATA_TYPE, messageDataType);
exportFile(exportText, absoluteWorkspacePath + File.separator + outputPath + File.separator, tableName, ".sql");
}
if (createTableInputStream != null) {
createTableInputStream.close();
}
The Problem is in this method:
public String getString(InputStream is) throws IOException {
You close the the reader and stream at the end. (When you close the reader the streams in it are automatic close.
Edit: You should close the reader. getString(InputStream is) throws IOException returns always the same String or? Read it before you go in the loop and reuse the String everytime.
String exportText = getString("val_table_create.sql");
for (Sheet sheet : bookSheets) {
setHeader(table, sheet);
String newExportText = exportText.replaceAll(TABLE_NAME, tableName);
messageDataType);
exportFile(newExportText, absoluteWorkspacePath + File.separator + outputPath + File.separator, tableName, ".sql");
}
Change your getString Method to this:
public String getString(String resourceName) throws IOException {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
String line;
try {
InputStream createTableInputStream reader.getResourceAsStream(resourceName);
reader = new BufferedReader(new InputStreamReader(is));
while ((line = reader.readLine()) != null) {
sb.append(line + System.lineSeparator());
}
} catch (IOException ex) {
ex.printStackTrace();
}
return sb.toString();
}
and close there all the streams. Now you have one place where you load your file.
createTableInputStream will be closed for the first time you call getString method so for next sheet in loop you will get stream closed.
It's a better practice to close the stream in the method who created it. You should close the stream in run method instead.
I am trying to replace a string from a js file which have content like this
........
minimumSupportedVersion: '1.1.0',
........
now 'm trying to replace the 1.1.0 with 1.1.1. My code is searching the text but not replacing. Can anyone help me with this. Thanks in advance.
public class replacestring {
public static void main(String[] args)throws Exception
{
try{
FileReader fr = new FileReader("G:/backup/default0/default.js");
BufferedReader br = new BufferedReader(fr);
String line;
while((line=br.readLine()) != null) {
if(line.contains("1.1.0"))
{
System.out.println("searched");
line.replace("1.1.0","1.1.1");
System.out.println("String replaced");
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
First, make sure you are assigning the result of the replace to something, otherwise it's lost, remember, String is immutable, it can't be changed...
line = line.replace("1.1.0","1.1.1");
Second, you will need to write the changes back to some file. I'd recommend that you create a temporary file, to which you can write each `line and when finished, delete the original file and rename the temporary file back into its place
Something like...
File original = new File("G:/backup/default0/default.js");
File tmp = new File("G:/backup/default0/tmpdefault.js");
boolean replace = false;
try (FileReader fr = new FileReader(original);
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter(tmp);
BufferedWriter bw = new BufferedWriter(fw)) {
String line = null;
while ((line = br.readLine()) != null) {
if (line.contains("1.1.0")) {
System.out.println("searched");
line = line.replace("1.1.0", "1.1.1");
bw.write(line);
bw.newLine();
System.out.println("String replaced");
}
}
replace = true;
} catch (Exception e) {
e.printStackTrace();
}
// Doing this here because I want the files to be closed!
if (replace) {
if (original.delete()) {
if (tmp.renameTo(original)) {
System.out.println("File was updated successfully");
} else {
System.err.println("Failed to rename " + tmp + " to " + original);
}
} else {
System.err.println("Failed to delete " + original);
}
}
for example.
You may also like to take a look at The try-with-resources Statement and make sure you are managing your resources properly
If you're working with Java 7 or above, use the new File I/O API (aka NIO) as
// Get the file path
Path jsFile = Paths.get("C:\\Users\\UserName\\Desktop\\file.js");
// Read all the contents
byte[] content = Files.readAllBytes(jsFile);
// Create a buffer
StringBuilder buffer = new StringBuilder(
new String(content, StandardCharsets.UTF_8)
);
// Search for version code
int pos = buffer.indexOf("1.1.0");
if (pos != -1) {
// Replace if found
buffer.replace(pos, pos + 5, "1.1.1");
// Overwrite with new contents
Files.write(jsFile,
buffer.toString().getBytes(StandardCharsets.UTF_8),
StandardOpenOption.TRUNCATE_EXISTING);
}
I'm assuming your script file size doesn't cross into MBs; use buffered I/O classes otherwise.