I have a .txt file which contains a list of stuff I want to store in an Array and use throughout my application. To achieve this I created the following class:
public class Sort {
ArrayList<String> sorted = new ArrayList<String>();
public Sort() throws IOException {
Scanner scanner = new Scanner(new FileReader("/home/scibor/coding/src/com/myapp/readThis.txt"));
while(scanner.hasNextLine()){
sorted.add(scanner.nextLine());
}
}
}
So I have a .txt file with a bunch of stuff in it, and then I create this class specifically for that case. Now when I want to access these things in the .txt file in an ArrayList in one of my other classes, I figure:
Sort sort = new Sort();
sort.sorted; //can use the arrayList like so
Instead I get a message that says UnhandledException: java.io.IOException
I've tried several variations of this using try/catch, BufferedReader with try/catch/finally and ultimately all of them have some sort of error pertaining to the Exceptions that are raised by reading in a file. What am I doing wrong here?
EDIT: As per one of the suggestions, I have tried a radically different approach as below:
public class Sort {
List<String> sorted;
public Sort(Context context){
sorted = new ArrayList<String>();
AssetManager assetManager = context.getAssets();
try {
InputStream read = assetManager.open("readThis.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(read));
while(reader.readLine() != null){
sorted.add(reader.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
This seems to get me further, and is probably very close to the correct answer. When I create Sort mySortedObject = new Sort(this); there are no errors generated. When I finally access the ArrayList though, as follows:
for(String name: mySortedObject.sort){
if(name.equals("Whatever"){
//run this
}
}
}
I get a NullPointerException on the line containing the if statement. So the object was successfully created...but not quite?
EDIT: The "readThis.txt" file is located in /assets
I believe the file "/home/scibor/coding/src/com/myapp/readThis.txt" does not exist on your phone (and for a good reason). You will need to add your .txt as an asset to your project and load it using the AssetManager.open()-method
Edit:
In your edited code, your NullPointerException is caused by you calling .readLine() twice in each iteration.
Solution:
String line = null;
while(true){
line = reader.readLine();
if (line == null) break;
sorted.add(line);
}
Related
I am writing code to process a list of tar.gz files, inside which there are multiple, csv files. I have encountered the error below
com.opencsv.exceptions.CsvMalformedLineException: Unterminated quoted field at end of CSV line. Beginning of lost text: [,,,,,,
]
at com.opencsv.CSVReader.primeNextRecord(CSVReader.java:245)
at com.opencsv.CSVReader.flexibleRead(CSVReader.java:598)
at com.opencsv.CSVReader.readNext(CSVReader.java:204)
at uk.ac.shef.inf.analysis.Test.readAllLines(Test.java:64)
at uk.ac.shef.inf.analysis.Test.main(Test.java:42)
And the code causing this problem is below, on line B.
public class Test {
public static void main(String[] args) {
try {
Path source = Paths.get("/home/xxxx/Work/data/amazon/labelled/small/Books_5.json.1.tar.gz");
InputStream fi = Files.newInputStream(source);
BufferedInputStream bi = new BufferedInputStream(fi);
GzipCompressorInputStream gzi = new GzipCompressorInputStream(bi);
TarArchiveInputStream ti = new TarArchiveInputStream(gzi);
CSVParser parser = new CSVParserBuilder().withStrictQuotes(true)
.withQuoteChar('"').withSeparator(',').
.withEscapeChar('|'). // Line A
build();
BufferedReader br = null;
ArchiveEntry entry;
entry = ti.getNextEntry();
while (entry != null) {
br = new BufferedReader(new InputStreamReader(ti)); // Read directly from tarInput
System.out.format("\n%s\t\t > %s", new Date(), entry.getName());
try{
CSVReader reader = new CSVReaderBuilder(br).withCSVParser(parser)
.build();
List<String[]> r = readAllLines(reader);
} catch (Exception ioe){
ioe.printStackTrace();
}
System.out.println(entry.getName());
entry=ti.getNextEntry(); // Line B
}
}catch (Exception e){
e.printStackTrace();
}
}
private static List<String[]> readAllLines(CSVReader reader) {
List<String[]> out = new ArrayList<>();
int line=0;
try{
String[] lineInArray = reader.readNext();
while(lineInArray!=null) {
//System.out.println(Arrays.asList(lineInArray));
out.add(lineInArray);
line++;
lineInArray=reader.readNext();
}
}catch (Exception e){
System.out.println(line);
e.printStackTrace();
}
System.out.println(out.size());
return out;
}
}
I also attach a screenshot of the actual line within the csv file that caused this problem here, look at line 5213. I also include a test tar.gz file here: https://drive.google.com/file/d/1qHfWiJItnE19-BFdbQ3s3Gek__VkoUqk/view?usp=sharing
While debugging, I have some questions.
I think the issue is the \ character in the data file (line 5213 above), which is the escape character in Java. I verified this idea by adding line A to my code above, and it works. However, obviously I don't want to hardcode this as there can be other characters in the data causing same issue. So my question 1 is: is there anyway to tell Java to ignore escape characters? Something like the opposite of withEscapeChar('|')? UPDATE: the answer is to use '\0', thanks to the first comment below.
When debugging, I notice that my program stops working on the next .csv file within the tar.gz file as soon as it hit the above exception. To explain what I mean, inside the tar.gz file included in the above link, there are two csvs: _10.csv and _110.csv. The problematic line is in _10.csv. When my program hit that line, an exception is thrown and the program moves on to the next file _110.csv (entry=ti.getNextEntry();). This file is actually fine, but the method readAllLines that is supposed to read this next csv file will throw the same exception immediately on the first line. I don't think my code is correct, especially the while loop: I suspect the input stream was still stuck at the previous position that caused the exception. But I don't know how to fix this. Help please?
using RFC4180Parser worked for me.
Trying to save arraylist items to a text file, I kind of have it working but it saves the whole arraylist on one line
I am hoping to save it per line and not have any duplicates or the empty brackets at the start, Any help would be much appreciated. Also if possible to remove the brackets around the text for easier reading into an arraylist
FileOutputStream is more fitting for when your data is already in a byte format. I suggest you use something like a PrintWriter.
PrintWriter pw = null;
try {
File file = new File("file.txt"); //edited
pw = new PrintWriter(file); //edited
for(String item: Subreddit_Array_List)
pw.println(item);
} catch (IOException e) {
e.printStackTrace();
}
finally{
pw.close();
}
Keep in mind this overwrites what was in the file before rather than appends to it. The output will be formatted like:
Cats
Dogs
Birds
You can iterate over the map and save all variables in separate lines.
Example:
private List<Object> objects;
private void example() {
//JDK >= 8
this.objects.forEach(this::writeInFile);
//JDK < 8
for (Object object : this.objects) {
this.writeInFile(object);
}
}
private void writeInFile(Object object) {
//your code here
}
Currently, I'm attempting (and failing) to read from a file in the context of this homework assignment. The program is supposed to return a list of the number of each word in a separate file when run, yet it returns nothing but a blank screen. I am making use of the File Reader object in Java, and using a scanner class to read individual words from that file reader.
I have already tried buffered reader in a similar instance. There is no file not found error, so that can't be it.
import java.util.*;
import java.io.*;
public class Driver {
public static void main(String[] args) {
FileReader inputStream = null;
try {
inputStream = new FileReader("C:\\Users\\[my username]\\Documents\\lorem ipsum.txt");
System.out.println("Testing.");
boolean placeholder = false;
WordBag textfile = new WordBag(2000);
Scanner scan = new Scanner(inputStream);
while (scan.hasNext()) {
Word temp = new Word(scan.next());
placeholder = textfile.add(temp);
if (placeholder = false) {
System.out.println("Addition failed.");
}
}
while (!textfile.isEmpty()) {
System.out.println(textfile.remove().toString());
}
}
catch (FileNotFoundException e){
System.out.println("File not found.");
}
}
}
The Word object type has two variables-- One which stores the string, and the second which stores the frequency with which the word appears in the file.
The WordBag object is essentially an array of these word objects, with some particular methods.
The expected output should be a list of the various words within the file. However, it is printing nothing whatsoever on the screen.
Edit: It is printing only "Testing." My apologies, I didn't describe the output accurately.
So I have a wordlist called wordlist.txt and I want to put all words that have a specific length, let's say 5, and put them in a list.
First I tried to just get all the words into a list, for testing purposes but I got an error "Cannot resolve symbol 'exists'" when I tried Files.exists, it works in the Main function but not in a class for some reason.
Image Error
ArrayList<String> list = new ArrayList<>();
private Path myFile = Paths.get("Resources/wordlist.txt");
if (Files.exists(myFile)){
try (Scanner fileScanner = new Scanner(myFile)){
while (fileScanner.hasNext()) {
list.add(fileScanner.nextLine());
}
} catch (IOException ioe){
System.out.println("The file doesn't exists!");
}
}
Firstly, remove the private modifier - it is not allowed to be inside a method. That should resolve your syntax error.
Secondly, I suggest you follow the folder structure as a brief example states below:
src/main/java
- Main.java
src/main/resources
- wordlist.txt
You are ready you can access the file using the ClassLoader. If Files.exists(myFile) returns true, the IOException won't be thrown. Try the following code:
ArrayList<String> list = new ArrayList<>();
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
File file = new File(classLoader.getResource("wordlist.txt").getFile());
try (Scanner fileScanner = new Scanner(file)) {
while (fileScanner.hasNext()) {
list.add(fileScanner.nextLine());
}
} catch (IOException ioe) {
System.out.println("The file doesn't exists!");
}
Finally, the label of the question doesn't match with what do you ask. I am not sure whether I understand "put all words" correctly. Anyway, let's suggest the text file contains one word on each line, thus check it's length and decide to add to the list or not.
while (fileScanner.hasNext()) {
String line = fileScanner.nextLine();
if (line.length() == 5) { // specific length, use a constant is better
list.add(line);
}
}
I believe that you need to add a "/" in the path like this: ("/Resources/wordlist.txt"), because of file pathing to your project.
Tutorial can be seen here
I wrote a simple program to read the content from text/log file to html with conditional formatting.
Below is my code.
import java.io.*;
import java.util.*;
class TextToHtmlConversion {
public void readFile(String[] args) {
for (String textfile : args) {
try{
//command line parameter
BufferedReader br = new BufferedReader(new FileReader(textfile));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
Date d = new Date();
String dateWithoutTime = d.toString().substring(0, 10);
String outputfile = new String("Test Report"+dateWithoutTime+".html");
FileWriter filestream = new FileWriter(outputfile,true);
BufferedWriter out = new BufferedWriter(filestream);
out.write("<html>");
out.write("<body>");
out.write("<table width='500'>");
out.write("<tr>");
out.write("<td width='50%'>");
if(strLine.startsWith(" CustomerName is ")){
//System.out.println("value of String split Client is :"+strLine.substring(16));
out.write(strLine.substring(16));
}
out.write("</td>");
out.write("<td width='50%'>");
if(strLine.startsWith(" Logged in users are ")){
if(!strLine.substring(21).isEmpty()){
out.write("<textarea name='myTextBox' cols='5' rows='1' style='background-color:Red'>");
out.write("</textarea>");
}else{
System.out.println("else if block:");
out.write("<textarea name='myTextBox' cols='5' rows='1' style='background-color:Green'>");
out.write("</textarea>");
} //closing else block
//out.write("<br>");
out.write("</td>");
}
out.write("</td>");
out.write("</tr>");
out.write("</table>");
out.write("</body>");
out.write("</html>");
out.close();
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
public static void main(String args[]) {
TextToHtmlConversion myReader = new TextToHtmlConversion();
String fileArray[] = {"D:/JavaTesting/test.log"};
myReader.readFile(fileArray);
}
}
I was thinking to enhance my program and the confusion is of either i should use Maps or properties file to store search string. I was looking out for a approach to avoid using substring method (using index of a line). Any suggestions are truly appreciated.
From top to bottom:
Don't use wildcard imports.
Don't use the default package
restructure your readFile method in more smaller methods
Use the new Java 7 file API to read files
Try to use a try-block with a resource (your file)
I wouldn't write continuously to a file, write it in the end
Don't catch general Exception
Use a final block to close resources (or the try block mentioned before)
And in general: Don't create HTML by appending strings, this is a bad pattern for its own. But well, it seems that what you want to do.
Edit
Oh one more: Your text file contains some data right? If your data represents some entities (or objects) it would be good to create a POJO for this. I think your text file contains users (right?). Then create a class called Users and parse the text file to get a list of all users in it. Something like:
List<User> users = User.parse("your-file.txt");
Afterwards you have a nice user object and all your ugly parsing is in one central point.