I used BufferedReader and FileReader to read a file but everytime I read it, it just displays no name found. Thanks in advance.
BufferedReader ifile = new BufferedReader (new FileReader ("data.txt"));
String N;
while(true)
{
N=ifile.readLine();
if (N == null){
System.out.print("\fNo name found\n");
break;
}
number = Integer.parseInt(ifile.readLine());
house = ifile.readLine();
form = ifile.readLine();
dob = ifile.readLine();
System.out.println("Name: " + N + "\nNumber: " + number + "\nHouse: " + house + "\nForm: " + form + "\nDate of Birth: " + dob);
}
ifile.close();
Answer might have already been given in another topic like: Read all lines with BufferedReader
So it might be a duplicate.
However when you read a file via BufferedReader it is recommended you do it like
FileReader filereader = new FileReader("data.txt");
BufferedReader ifile = new BufferedReader(filereader);
String N;
ArrayList<String> file_contents= new ArrayList<String>();
//List will now contain the whole txt
try {
while((N = input.readLine()) != null) {
file_contents.add(N);
}
ifile.close();
}
catch(IOException e){
e.printStackTrace();
}
And then break the list's contents to get what you want.
Using a try/catch block can avoid the error of not knowing how to handle that the file "data.txt" cannot be read.
Your way of doing it (while(true)) doesn't pass the name in any variable so it can be printed out and also just checks if the 1st line of your data.txt file is empty or not and does nothing with the remaining lines if that condition is true.
In addition to the above check if the source of your problem is in the txt file.
For example if its structure is the way you want it to be.
Related
I am writing to an internal file in Android Studio
String filename = "output.txt";
String fileContents = studentNum + ", " + lastName + ", " + firstName + ", " + radioValue + ", " + spinnerInfo + "\n"; // edit this to include all content
FileOutputStream outputStream;
try{
outputStream = openFileOutput(filename, Context.MODE_APPEND);
outputStream.write(fileContents.getBytes());
outputStream.close();
} catch(Exception e){
e.printStackTrace();
}
}
The code lets me write lines of data split with commas. I am able to then go to another activity and read it all out at once.
String file = "output.txt";
String line = "";
String data = "";
//File read operation
try {
FileInputStream fis = openFileInput(file); //A FileInputStream obtains input bytes from a file in a file system
InputStreamReader isr = new InputStreamReader(fis); //An InputStreamReader is a bridge from byte streams to character streams
BufferedReader br = new BufferedReader(isr); //Reads text from a character-input stream,
while ((line = br.readLine()) != null) {
data += (counter+1) + "\t"+ line +"\n";
counter++;
}
}catch (FileNotFoundException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
//Show the data
txtOutput.setText(data);
However I want to be able to read only one line of data per activity and when I click a button it transfers down to the next line of data. And goes in a carousel loop so once we reach the last line it will go to the first line of data once the button is clicked again
The easiest thing is probably just to keep a line number pointer (since you are reading by line), and read down that many lines to get where you want at each activity. If the file is large or you are otherwise performance conscious this is not a great option.
Both InputStream and Reader have a skip(<bytes>) method. You could also do it that way. Obviously if you use a stream you need to read by bytes not by line, so a little more trouble.
You could also use a RandomAccessFile that has a seek() method. Again this is accessed by byte index.
Im curious on how create an Inverted Index on data that doesn't fit into memory. So right now I'm reading a file directory and indexing the files based on the contents inside the file, I am using a HashMap to store the index. The code below is a snippet from a function I use and I call the function on an entire directory. What do I do if this directory was just massive and the HashMap can't fit all the entries. Yes, This does sound like premature optimization. Im just having fun. I don't want to use Lucene so don't even mention it because I'm tired as to seeing that as the majority answer to "Index" stuff. This HashMap is my only constraint everything else is stored in files to easily reference stuff later on.
Im just curious how I can do this since it stores it in the map like so
keyword -> file1,file2,file3,etc..(locations)
keyword2 -> file9,file11,file13,etc..(locations)
My thoughts were to create a file which would some how be able to update itself to be like the format above but I feel thats not efficient.
Code Snippet
br = new BufferedReader(new FileReader(file));
while ((line = br.readLine()) != null) {
for (String _word : line.split("\\W+")) {
word = _word.toLowerCase();
if (!ignore_words.contains(word)) {
fileLocations = index.get(word);
if (fileLocations == null) {
fileLocations = new LinkedList<Long>();
index.put(word, fileLocations);
}
fileLocations.add(file_offset);
}
}
}
br.close();
Update:
So I managed to come up with something, but performance wise I feel this is slow, especially if there was a large amount of data. I basically created a file that would just have to word and its offset on each line the word appeared.Lets name it index.txt.
It had the format of like so
word1:offset
word2:offset
word1:offset <-encountered again.
word3:offset
etc...
I then created multiple files for each word and appended the offset to that file each time it was encountered in the index.txt file.
So basically the format of the word files are like so
word1.txt -- Format
word1:offset1:offset2:offset3:offset4...and so on
each time word1 is encountered in the index.txt file it would append it to the word1.txt file and add to end.
Then finally, I go through all the word files I created and overwrite the index.txt file with the final output in the index file looking like so
word1:offset1:offset2:offset3:offset4:...
word2:offset9:offset11:offset13:offset14:...
etc..
Then to finish it up, I delete all the word files.
The nasty code snippet for this is below, its a fair amount.
public void createIndex(String word, long file_offset)
{
PrintWriter writer;
try {
writer = new PrintWriter(new FileWriter(this.file,true));
writer.write(word + ":" + file_offset + "\n");
writer.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
public void mergeFiles()
{
String line;
String wordLine;
String[] contents;
String[] wordContents;
BufferedReader reader;
BufferedReader mergeReader;
PrintWriter writer;
PrintWriter mergeWriter;
try {
reader = new BufferedReader(new FileReader(this.file));
while((line = reader.readLine()) != null)
{
contents = line.split(":");
writer = new PrintWriter(new FileWriter(
new File(contents[0] + ".txt"),true));
if(this.words.get(contents[0]) == null)
{
this.words.put(contents[0], contents[0]);
writer.write(contents[0] + ":");
}
writer.write(contents[1] + ":");
writer.close();
}
//This could be put in its own method below.
mergeWriter = new PrintWriter(new FileWriter(this.file));
for(String word : this.words.keySet())
{
mergeReader = new BufferedReader(
new FileReader(new File(word + ".txt")));
while((wordLine = mergeReader.readLine()) != null)
{
mergeWriter.write(wordLine + "\n");
}
}
mergeWriter.close();
deleteFiles();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
public void deleteFiles()
{
File toDelete;
for(String word : this.words.keySet())
{
toDelete = new File(word + ".txt");
if(toDelete.exists())
{
toDelete.delete();
}
}
}
I know previous questions LIKE this one have been asked, but this question has to do with the specifics of the code that I have written. I am trying to update a single line of code on a file that will be permanently updated even when the program terminates so that the data can be brought up again. The method that I am writing currently looks like this (no compile errors found with eclipse)
public static void editLine(String fileName, String name, int element,
String content) throws IOException {
try {
// Open the file specified in the fileName parameter.
FileInputStream fStream = new FileInputStream(fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(
fStream));
String strLine;
StringBuilder fileContent = new StringBuilder();
// Read line by line.
while ((strLine = br.readLine()) != null) {
String tokens[] = strLine.split(" ");
if (tokens.length > 0) {
if (tokens[0].equals(name)) {
tokens[element] = content;
String newLine = tokens[0] + " " + tokens[1] + " "
+ tokens[2];
fileContent.append(newLine);
fileContent.append("\n");
} else {
fileContent.append(strLine);
fileContent.append("\n");
}
}
/*
* File Content now has updated content to be used to override
* content of the text file
*/
FileWriter fStreamWrite = new FileWriter(fileName);
BufferedWriter out = new BufferedWriter(fStreamWrite);
out.write(fileContent.toString());
out.close();
// Close InputStream.
br.close();
}
} catch (IOException e) {
System.out.println("COULD NOT UPDATE FILE!");
System.exit(0);
}
}
If you could look at the code and let me know what you would suggest, that would be wonderful, because currently I am only getting my catch message.
Okay. First off the bat, StringBuilder fileContent = new StringBuilder(); is bad practice as this file could well be larger than the user's available memory. You should not keep much of the file in memory at all. Do this by reading into a buffer, processing the buffer (adjusting it if necessary), and writing the buffer to a new file. When done, delete the old file and rename the secondary to the old one's name. Hope this helps.
I have a BufferedWriter which is being used to write to a file the users details. I have noticed, however, it is not writing to file in the format I want it to, I can't seem to find a method which allows me to write text on a new line without it writing over what is already there or copy out the text already in the file. Is there any way I can edit the following code, to allow it to the above?
Details = "Name: " + name + " CardNo: " + CardNo + " Current Balance: " + balance + " overdraft? " + OverDraft + " OverDraftLimit: " + OverDraftLimit + " pin: " + PinToWrite;
try{
//Create writer to write to files.
File file = new File(DirToWriteFile);
FileOutputStream fos = new FileOutputStream(file, true);
Writer bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF8"));
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader("VirtualATM.txt");
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
String currentData = "";
while((currentData=bufferedReader.readLine()) != null) {
line = currentData;
bw.write(currentData);
((BufferedWriter) bw).newLine();
}
bw.write(Details);
System.out.println("Account created!");
There is no problem with the program (all variables work properly and have been declared somewhere) I have only posted a snippet of the code which is relevant to the question. The current output to the file after running it a few times looks like this
I've got it! Change:
while((currentData=bufferedReader.readLine()) != null) {
line = currentData;
bw.write(currentData);
((BufferedWriter) bw).newLine();
}
bw.write(Details);
to:
bw.append(Details);
((BufferedWriter) bw).newLine();
This ensures that no data will be written twice and it will not copy out any text besides the information gained from the user.
I have a method like this:
public int getIncrement() {
String extractFolder = "/mnt/sdcard/MyFolder";
boolean newFolder = new File(extractFolder).mkdir();
int counter = 0;
try {
File root = new File(extractFolder);
if (root.canWrite()){
File gpxfile = new File(root, "gpxfile.txt");
FileWriter gpxwriter = new FileWriter(gpxfile);
BufferedWriter out = new BufferedWriter(gpxwriter);
Scanner scanner = new Scanner(new FileInputStream(gpxfile.getAbsolutePath()), "UTF-8");
Log.i("PATH: ", extractFolder + "/gpxfile.txt");
while(scanner.hasNextLine()) {
String inc = scanner.nextLine();
counter = Integer.parseInt(inc);
Log.i("INSIDE WHILE: ", Integer.toString(counter));
}
counter++;
out.write(Integer.toString(counter));
out.close();
}
} catch (IOException e) {
Log.e("GEN_PCN: ", "Could not write file " + e.getMessage());
}
return counter;
}
What I am trying to accomplish is returning the content of this file, and increment the integer by 1. But it seems that I can't get in the while loop, because LogCat doesn't print out anything. Yes, am sure that the path is correct.
I guess the constructor of FileWriter gpxwriter has already blanked out the file by the time the Scanner is created, so the file is empty and hasNextLine returns false. Why do you open a file for writing when you want to read it?
From what I can tell the file doesn't exist. Try adding gpxfile.createNewFile()
To get a little more in depth, creating a File instance, does not create a file on the file system.
So, this line -> File gpxfile = new File(path, filename);
is not sufficient to create the file on the sd card. You must follow it with
gpxfile.createNewFile() which quoting the docs says:
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file.
OK I MARK YOUR FILE NAME
Just add a BACKSLASH in extractFolder at END
v
v
v
String extractFolder = "/mnt/sdcard/MyFolder/";
^ // <--- HERE
^
^
Because File gpxfile = new File(root, "gpxfile.txt"); doesn't have BackSlash / as Log have
Just try Once Following:
while(scanner.hasNextLine()) {
String inc = scanner.nextLine();
// // counter = Integer.parseInt(inc);
Log.i("INSIDE WHILE: ", inc);
System.out.println("Next Line ::"+inc); // Also check this
}