I have an assignment where I need to read a file's contents in reverse, like this:
Original:
This is how you reverse a file, 10
New:
10 ,file a reverse you how is This
Here's the code I have:
public static void main(String [args]{
Path file = Paths.get("C:\\Java\\Sample.txt");
InputStream input = null;
ArrayList<String> words = new ArrayList<String>();
try{
input = Files.newInputStream(files);
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String s;
while((s = reader.readLine()) != null)
words.add(s);
for(int i = words.size() - 1; i >= 0; i--){
System.out.print(words.get(i));
}
catch(Exception e){
System.out.println(e);
}
}
Sorry if the formatting is off. The program simply reads the file in original form. What am I doing wrong? Can anyone explain what I need to have this print backwards? My textbook doesn't explain anything.
Also, I realize that my catch block is possibly too broad. I'll work on that.
EDIT: I forgot to add the ArrayList code when typing this out. It exists already in my original program.
Thank you
while((s = reader.readLine()) != null)
words.add(s);
The second line implies that s holds words, but the first line reads a line at a time. You need to read a word at a time, or split the lines into words.
I am trying to create a program that takes an inputted text file and reads the lines one by one. It then needs to store the most recently read lines (the number of lines depends on the parameter lines) in an array and then I need to print the lines using PrintWriter.
I started the first part but I'm not sure if I have the right idea. If anyone can help me on the second part as well that would be very appreciated!
public void RecentLines(Reader in, Writer out, int lines) throws IOException {
BufferedReader r3ader = new BufferedReader(in);
String str;
while((str = r3ader.readLine()) != null){
String[] arr = str.split(" ");
for( int i =0; i < lines; i++){
arr[i] = r3ader.readLine();
}
}
EDIT
the full question is this:
Create a program which reads lines from IN, one line at the time until the end. Your method must maintain an internal buffer that stores the most recently read lines (this might be best done using an array). Once the method reaches the end of the file, it should print the lines stored in the internal buffer into out, probably best done by creating a PrintWriter to decorate this Writer. (Except for your debugging purposes during the development stage, this method should not print anything to System.out.)
Try this one:
public void RecentLines(Reader in, Writer out, int lines) throws IOException {
BufferedReader r3ader = new BufferedReader(in);
String str;
int i=0;
String[] lineArray = new String[lines];
while((str = r3ader.readLine()) != null){
lines[i%lines] = str;
i++;
if(!r3ader.hasNextLine()){
break;
}
}
sounds like a task for data structures. Queue seems to be the best fit for a given task.
public void RecentLines(Reader in, Writer out, int lines) throws IOException {
BufferedReader r3ader = new BufferedReader(in);
BufferedWriter wout = new BufferedWriter(out);
String str;
Queue<String> content = new LinkedList<String>();
int i = 0;
while ((str = r3ader.readLine()) != null) {
if (i >= lines) {
content.remove();
}
content.add(str);
i++;
}
wout.write(String.valueOf(content));
}
In Java, is there any method to read a particular line from a file? For example, read line 32 or any other line number.
For small files:
String line32 = Files.readAllLines(Paths.get("file.txt")).get(32)
For large files:
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
line32 = lines.skip(31).findFirst().get();
}
Unless you have previous knowledge about the lines in the file, there's no way to directly access the 32nd line without reading the 31 previous lines.
That's true for all languages and all modern file systems.
So effectively you'll simply read lines until you've found the 32nd one.
Not that I know of, but what you could do is loop through the first 31 lines doing nothing using the readline() function of BufferedReader
FileInputStream fs= new FileInputStream("someFile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
for(int i = 0; i < 31; ++i)
br.readLine();
String lineIWant = br.readLine();
Joachim is right on, of course, and an alternate implementation to Chris' (for small files only because it loads the entire file) might be to use commons-io from Apache (though arguably you might not want to introduce a new dependency just for this, if you find it useful for other stuff too though, it could make sense).
For example:
String line32 = (String) FileUtils.readLines(file).get(31);
http://commons.apache.org/io/api-release/org/apache/commons/io/FileUtils.html#readLines(java.io.File, java.lang.String)
You may try indexed-file-reader (Apache License 2.0). The class IndexedFileReader has a method called readLines(int from, int to) which returns a SortedMap whose key is the line number and the value is the line that was read.
Example:
File file = new File("src/test/resources/file.txt");
reader = new IndexedFileReader(file);
lines = reader.readLines(6, 10);
assertNotNull("Null result.", lines);
assertEquals("Incorrect length.", 5, lines.size());
assertTrue("Incorrect value.", lines.get(6).startsWith("[6]"));
assertTrue("Incorrect value.", lines.get(7).startsWith("[7]"));
assertTrue("Incorrect value.", lines.get(8).startsWith("[8]"));
assertTrue("Incorrect value.", lines.get(9).startsWith("[9]"));
assertTrue("Incorrect value.", lines.get(10).startsWith("[10]"));
The above example reads a text file composed of 50 lines in the following format:
[1] The quick brown fox jumped over the lazy dog ODD
[2] The quick brown fox jumped over the lazy dog EVEN
Disclamer: I wrote this library
Although as said in other answers, it is not possible to get to the exact line without knowing the offset (pointer) before. So, I've achieved this by creating an temporary index file which would store the offset values of every line. If the file is small enough, you could just store the indexes (offset) in memory without needing a separate file for it.
The offsets can be calculated by using the RandomAccessFile
RandomAccessFile raf = new RandomAccessFile("myFile.txt","r");
//above 'r' means open in read only mode
ArrayList<Integer> arrayList = new ArrayList<Integer>();
String cur_line = "";
while((cur_line=raf.readLine())!=null)
{
arrayList.add(raf.getFilePointer());
}
//Print the 32 line
//Seeks the file to the particular location from where our '32' line starts
raf.seek(raf.seek(arrayList.get(31));
System.out.println(raf.readLine());
raf.close();
Also visit the Java docs on RandomAccessFile for more information:
Complexity: This is O(n) as it reads the entire file once. Please be aware for the memory requirements. If it's too big to be in memory, then make a temporary file that stores the offsets instead of ArrayList as shown above.
Note: If all you want in '32' line, you just have to call the readLine() also available through other classes '32' times. The above approach is useful if you want to get the a specific line (based on line number of course) multiple times.
Another way.
try (BufferedReader reader = Files.newBufferedReader(
Paths.get("file.txt"), StandardCharsets.UTF_8)) {
List<String> line = reader.lines()
.skip(31)
.limit(1)
.collect(Collectors.toList());
line.stream().forEach(System.out::println);
}
No, unless in that file format the line lengths are pre-determined (e.g. all lines with a fixed length), you'll have to iterate line by line to count them.
In Java 8,
For small files:
String line = Files.readAllLines(Paths.get("file.txt")).get(n);
For large files:
String line;
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
line = lines.skip(n).findFirst().get();
}
In Java 7
String line;
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
for (int i = 0; i < n; i++)
br.readLine();
line = br.readLine();
}
Source: Reading nth line from file
If you are talking about a text file, then there is really no way to do this without reading all the lines that precede it - After all, lines are determined by the presence of a newline, so it has to be read.
Use a stream that supports readline, and just read the first X-1 lines and dump the results, then process the next one.
It works for me:
I have combined the answer of
Reading a simple text file
But instead of return a String I am returning a LinkedList of Strings. Then I can select the line that I want.
public static LinkedList<String> readFromAssets(Context context, String filename) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open(filename)));
LinkedList<String>linkedList = new LinkedList<>();
// do reading, usually loop until end of file reading
StringBuilder sb = new StringBuilder();
String mLine = reader.readLine();
while (mLine != null) {
linkedList.add(mLine);
sb.append(mLine); // process line
mLine = reader.readLine();
}
reader.close();
return linkedList;
}
Use this code:
import java.nio.file.Files;
import java.nio.file.Paths;
public class FileWork
{
public static void main(String[] args) throws IOException {
String line = Files.readAllLines(Paths.get("D:/abc.txt")).get(1);
System.out.println(line);
}
}
You can use LineNumberReader instead of BufferedReader. Go through the api. You can find setLineNumber and getLineNumber methods.
You can also take a look at LineNumberReader, subclass of BufferedReader. Along with the readline method, it also has setter/getter methods to access line number. Very useful to keep track of the number of lines read, while reading data from file.
public String readLine(int line){
FileReader tempFileReader = null;
BufferedReader tempBufferedReader = null;
try { tempFileReader = new FileReader(textFile);
tempBufferedReader = new BufferedReader(tempFileReader);
} catch (Exception e) { }
String returnStr = "ERROR";
for(int i = 0; i < line - 1; i++){
try { tempBufferedReader.readLine(); } catch (Exception e) { }
}
try { returnStr = tempBufferedReader.readLine(); } catch (Exception e) { }
return returnStr;
}
you can use the skip() function to skip the lines from begining.
public static void readFile(String filePath, long lineNum) {
List<String> list = new ArrayList<>();
long totalLines, startLine = 0;
try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
totalLines = Files.lines(Paths.get(filePath)).count();
startLine = totalLines - lineNum;
// Stream<String> line32 = lines.skip(((startLine)+1));
list = lines.skip(startLine).collect(Collectors.toList());
// lines.forEach(list::add);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
list.forEach(System.out::println);
}
EASY WAY - Reading a line using line number.
Let's say Line number starts from 1 till null .
public class TextFileAssignmentOct {
private void readData(int rowNum, BufferedReader br) throws IOException {
int n=1; //Line number starts from 1
String row;
while((row=br.readLine()) != null) { // Reads every line
if (n == rowNum) { // When Line number matches with which you want to read
System.out.println(row);
}
n++; //This increments Line number
}
}
public static void main(String[] args) throws IOException {
File f = new File("../JavaPractice/FileRead.txt");
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
TextFileAssignmentOct txf = new TextFileAssignmentOct();
txf.readData(4, br); //Read a Specific Line using Line number and Passing buffered reader
}
}
for a text file you can use an integer with a loop to help you get the number of the line, don't forget to import the classes we are using in this example
File myObj = new File("C:\\Users\\LENOVO\\Desktop\\test.txt");//path of the file
FileReader fr = new FileReader(myObj);
fr.read();
BufferedReader bf = new BufferedReader(fr); //BufferedReader of the FileReader fr
String line = bf.readLine();
int lineNumber = 0;
while (line != null) {
lineNumber = lineNumber + 1;
if(lineNumber == 7)
{
//show line
System.out.println("line: " + lineNumber + " has :" + line);
break;
}
//lecture de la prochaine ligne, reading next
line = bf.readLine();
}
They are all wrong I just wrote this in about 10 seconds.
With this I managed to just call the object.getQuestion("linenumber") in the main method to return whatever line I want.
public class Questions {
File file = new File("Question2Files/triviagame1.txt");
public Questions() {
}
public String getQuestion(int numLine) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(file));
String line = "";
for(int i = 0; i < numLine; i++) {
line = br.readLine();
}
return line; }}
I am entering values to Bidimap. In each loop I am put(ing) values into the Bidimap and I am also printing the size of the Bidimap. It is always 1. I have also checked value of map through debbugger and it shows only one value which is the present value being put in the most recent iteration in the map. What is going wrong here? How am I suppose to save key-value in the Bidimap.
Please find below the complete code.
public static void main(String args[])
{
//Read file
BufferedReader br = null;
int wordCount=0;
String wordArray[] = null;
BidiMap<String, Integer> map = new DualHashBidiMap<String, Integer>();
try {
String sCurrentLine;
br = new BufferedReader(new InputStreamReader(new FileInputStream("C:\\IASTATE\\test.txt"), StandardCharsets.UTF_16));
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
wordArray = sCurrentLine.split("\\s+");
wordCount += wordArray.length;
}
//Read word 1,word 2,word 3
int count;
String key;
for(int i=0;i<wordArray.length;i++)
{
key=wordArray[i]+wordArray[i+1]+wordArray[i+2];
//Compare Hashmap if the String {'word 1','word 2','word 3'}
//exists
if(map.containsKey(key))
{
//If exists increment counter
count=(Integer) map.get(key);
count++;
map.put(key, count);
}
else
{
//If doesnot exist push String {'word 1','word 2','word 3'}
//in the Hashmap and initialize counter to 1
map.put(key, 1);
}
key=null;
System.out.println("Size of Map"+map.size());
}
} catch (IOException e) {
e.printStackTrace();
}
}
test.txt content is
This is line one
This is line two
This is line three
This is line four
You're reading every single line of the file but you're not processing any of those lines until after you've finished:
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
wordArray = sCurrentLine.split("\\s+");
wordCount += wordArray.length;
}
// Now you're messing about with wordArray, which is the _last_ line.
It's possible that your intent is to append all the words of each line to the wordArray array but that's not what you're doing.
That means you're only processing the last line of your file. If the last line is truly "this is line four", I'd still expect two entries, one for "this is line" and another for "is line four". But I'd fix up the problem described above before you start worrying about that.
By fixing it, I mean not overwriting wordArray every time a line is read in but instead appending to that array.
I have a text file where each line is a path of word strings word1/word2/.../wordn and I want to query the file. I need to build a tree which stores the words and each line of the file as a path so that anytime I search for a word, I get the word-node and all the paths this word belongs to. I was wondering if there is a build-in tree/graph related library in java or if there is a suitable particular tree structure I could use for the current problem. Actually, my basic idea is to construct a tree so that I read the file by line and add the nodes and line-path to that tree. Any ideas-suggestions?
I'd investigate storing the file in an XML Document and using XPath to search it. Xerces is a good start. Each part of the file (word1/) would be a node with subsequent words (word2) as a child.
I would build a class that holds a word and the set of lines that contain that word.
When traversing the file's lines, keep a map (java.util.HashMap or java.util.TreeMap, depending on how you need to use it later) with words (Strings) as keys, and the class above as values. For each word on a line, look it up in the dictionary, and add the line to its entry (or add a new entry if it isn't already there).
Looking up which lines the word occur in is a simple map lookup after you have scanned the file.
What you have is not really a tree at all. I would use a Map<String, List<String>> to store the list of lines that contains each word. This uses O(n) memory and has fast lookup. Example code:
import java.util.*;
import java.io.*;
public class WordNodes
{
Map<String, List<String>> map = new HashMap<String, List<String>>();
void readInputFile(String filename) throws IOException, FileNotFoundException
{
FileReader fileReader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(fileReader);
try
{
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
for (String word: line.split("/"))
{
List<String> list = map.get(word);
if (list == null)
{
list = new ArrayList<String>();
map.put(word, list);
}
list.add(line);
}
}
} finally {
bufferedReader.close();
}
}
void run() throws IOException, FileNotFoundException
{
readInputFile("file.txt");
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
try
{
while (true)
{
String word = bufferedReader.readLine();
List<String> lines = map.get(word);
if (lines == null)
{
System.out.println("Word not found.");
}
else
{
for (String line: lines)
{
System.out.println(line);
}
}
}
} finally {
bufferedReader.close();
}
}
public static void main(String[] args) throws Exception
{
new WordNodes().run();
}
}
My first though is similar to Liedman's, but slightly different: Rather than creating a new class for the lines, just use a Set<String> (HashSet<String>) or List<String> (ArrayList<String>).