I am trying to get the number of lines of code from a java file. But I am having trouble counting them.
First I tried to skip them with ifs, but my idea does not work. Now I am counting the same lines with comments, my Java file has this header. Any ideas, I am stuck in how to count them.
My if is for getting the number of lines with the comments block. I trying to make a subtract.
/*
example
example
*/
int totalLoc = 0;
int difference = 0;
while((line =buff.readLine()) !=null){
if((line.trim().length() !=0 &&(!line.contains("/*") ||!line.contains("*/")) )){
if(line.startsWith("/*")){
difference++;
}else if(linea.startsWith("*/")){
difference++;
}else{
difference++;
}
}
}
If you want to count lines in any file write below method and pass the fileName as input to below method and it will return counts.
public int count(String filename) throws IOException
{
InputStream is = new BufferedInputStream(new FileInputStream(filename));
try
{
byte[] c = new byte[1024];
int count = 0;
int readChars = 0;
boolean empty = true;
while ((readChars = is.read(c)) != -1)
{
empty = false;
for (int i = 0; i < readChars; ++i)
{
if (c[i] == '\n')
++count;
}
}
return (count == 0 && !empty) ? 1 : count;
}
finally
{
is.close();
}
}
Got the solution try below code it will print all multiline comments as well as total lines of multiline comments found in a file.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LinesOfCode {
public static void main(String[] args) {
try {
String s = readFile("D:\\src\\SampleClass.java");
Pattern p = Pattern.compile("/\\*[\\s\\S]*?\\*/");
Matcher m = p.matcher(s);
int total = 0;
while (m.find()) {
String lines[] = m.group(0).split("\n");
for (String string : lines) {
System.out.println(string);
total++;
}
}
System.out.println("Total line for comments = " + total);
} catch (Exception e) {
e.printStackTrace();
}
}
private static String readFile(String path) throws IOException {
FileInputStream stream = new FileInputStream(new File(path));
try {
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0,
fc.size());
/* Instead of using default, pass in a decoder. */
return Charset.defaultCharset().decode(bb).toString();
} finally {
stream.close();
}
}
}
http://ostermiller.org/findcomment.html
check out this link it will help you more.
and by using this expression => (/*([^]|[\r\n]|(*+([^/]|[\r\n])))*+/)|(//.)
you can count both comments single line and multi line !!
Related
How can I efficiently determine the possition of the last newline from a specific part from a file?
e.g. I tried this
BufferedReader br = new BufferedReader(new FileReader(file));
long length = file.length();
String line = null;
int tailLength = 0;
while ((line = br.readLine()) != null) {
System.out.println(line);
tailLength = line.getBytes().length;
}
int returnValue = length - tailLength;
but this will only return the possition of the very last newline in the whole file, and not the last newline in a section of the file. This section would be indicated by an int start; and an int end;
I think the most efficient approach is to start from the end of the file and read it in chunks. then, search it backwards for the first line.
i.e.
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class FileUtils {
static final int CHUNK_SIZE = 8 * 1024;
public static long getLastLinePosition(Path path) throws IOException {
try (FileChannel inChannel = FileChannel.open(path, StandardOpenOption.READ);
#SuppressWarnings("unused")
FileLock lock = inChannel.tryLock(0, Long.MAX_VALUE, true)) {
long fileSize = inChannel.size();
long mark = fileSize;
long position;
boolean ignoreCR = false;
while (mark > 0) {
position = Math.max(0, mark - CHUNK_SIZE);
MappedByteBuffer mbb = inChannel.map(FileChannel.MapMode.READ_ONLY, position, Math.min(mark, CHUNK_SIZE));
byte[] bytes = new byte[mbb.remaining()];
mbb.get(bytes);
for (int i = bytes.length - 1; i >= 0; i--, mark--) {
switch (bytes[i]) {
case '\n':
if (mark < fileSize) {
return mark;
}
ignoreCR = true;
break;
case '\r':
if (ignoreCR) {
ignoreCR = false;
} else if (mark < fileSize) {
return mark;
}
break;
}
}
mark = position;
}
}
return 0;
}
}
test file :
abc\r\n
1234\r\n
def\r\n
output : 11
learn more about java.nio.channels.FileChannel and java.nio.MappedByteBuffer :
http://tutorials.jenkov.com/java-nio/file-channel.html
https://examples.javacodegeeks.com/core-java/nio/filechannel/java-nio-channels-filechannel-example/
https://examples.javacodegeeks.com/core-java/nio/mappedbytebuffer/java-mappedbytebuffer-example/
http://tutorials.techmytalk.com/2014/11/05/java-nio-memory-mapped-files/
http://javarevisited.blogspot.nl/2012/01/memorymapped-file-and-io-in-java.html
EDIT :
if you are using Java 6, apply these changes to the above code :
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class FileUtils {
static final int CHUNK_SIZE = 8 * 1024;
public static long getLastLinePosition(String name) throws IOException {
FileChannel inChannel = null;
FileLock lock = null;
try {
inChannel = new RandomAccessFile(name, "r").getChannel();
lock = inChannel.tryLock(0, Long.MAX_VALUE, true);
// ...
} finally {
if (lock != null) {
lock.release();
}
if (inChannel != null) {
inChannel.close();
}
}
return 0;
}
}
Tips on choosing ideal buffer size :
https://stackoverflow.com/a/237495/3767784
https://stackoverflow.com/a/4638989/3767784
https://stackoverflow.com/a/19007819/3767784
Unfortunately you can't, I had to use RandomAccessFile which has getFilePointer() method which you can call after readLine(), but it is VERY SLOW and not UTF-8-aware.
I ended up implementing my own byte counting line reader.
Your naive solution will fail horribly when facing files with unicode, malformed or binary contents.
i have to write code that reads a text file and tells me how many lines and characters are in the file. I had it working but then i realized i had to ignore whitespace gaps so i wrote a method to do it. It works fine for one line but if i have more than one line it seems to count any whitespace. Any help would be appreciated
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Inputfile {
public static void main(String[] args) {
System.out.println("file name:");
Scanner sc = new Scanner(System.in);
String fn = sc.next();
int nrl = 0, nChar = 0;// nrl for number of lines
String line;// get line content variable
try {
File fs = new File("C:/" + fn);
nChar = length_ws(fs);
FileReader fr;// for reading file
fr = new FileReader(fs);
LineNumberReader lnr = new LineNumberReader(fr);
while (lnr.readLine() != null) {
nrl++;// count number of lines
}
JOptionPane.showMessageDialog(null, "number of lines:" + nrl + "\ntotal number of chars:" + nChar);
lnr.close();
fr.close();// close file
} catch (FileNotFoundException ex) {
System.err.println("File not found");
System.exit(0);
} catch (IOException ex) {
}
}
public static int length_ws(File f) throws IOException {
FileReader fr = null;
fr = new FileReader(f);
int i;
i = 0;
int c = 0;
do {
c = fr.read();// read character
if (c!= ' ') // count character except white space
i++;
} while (c != -1);
return i - 1;// because the is counted even the end of file
}
}
I don't think it is reading the space but the line feed (since these are char to).
I suggest that you do only read the file once (now it seems that you read it twice).
As char arrives
c = fr.read()
you evalute which char it is check out the asci table ASCII TABLE, you have space,tabs and line feeds (watch out depending on format you can have two chars LF and CR for line feed)
If you have valid char you advance your char counter.
If you have valid char for linefeed you advance your line count.
Hope this help and improves your coding, good luck
Seeing your comment I added this code, its not perfect but a start
int LF = 10; // Line feed
int CR = 13; // Chr retrun
int SPACE = 32;// Space
int TAB = 9; // Tab
FileReader fr = null;
int numberOfChars = 0;
int numberOfLines = 0;
int c = 0;
try {
do {
fr = new FileReader(new File("fileName.txt"));
c = fr.read();// read character
if (c > SPACE) { // space (ignoring also other chars
numberOfChars++;
}
if (c == LF) { // if does not have LF try CR
numberOfLines++;
}
} while (c != -1);
} catch (Exception e) {
e.printStackTrace();
if (fr != null) {
try {
fr.close();
} catch (IOException e1) {
}
}
}
What I am trying to do here is read a file and count each character. Each character should add +1 to the "int count" and then print out the value of "int count".
I hope that what I am trying to do is clear.
import java.io.*;
import java.util.Scanner;
public class ScanXan {
public static void main(String[] args) throws IOException {
int count = 0;
Scanner scan = null;
Scanner cCount = null;
try {
scan = new Scanner(new BufferedReader(new FileReader("greeting")));
while (scan.hasNextLine()) {
System.out.println(scan.nextLine());
}
}
finally {
if (scan != null) {
scan.close();
}
}
try {
cCount = new Scanner(new BufferedReader(new FileReader("greeting")));
while (cCount.hasNext("")) {
count++;
}
}
finally {
if (cCount != null) {
scan.close();
}
}
System.out.println(count);
}
}
Add a catch block to check for exception
Remove the parameter from hasNext("")
Move to the next token
cCount = new Scanner(new BufferedReader(new FileReader("greeting")));
while (cCount.hasNext()) {
count = count + (cCount.next()).length();
}
Using java 8 Stream API, you can do it as follow
package example;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CountCharacter {
private static int count=0;
public static void main(String[] args) throws IOException {
Path path = Paths.get("greeting");
try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) {
count = lines.collect(Collectors.summingInt(String::length));
}
System.out.println("The number of charachters is "+count);
}
}
Well if your looking for a way to count only all chars and integers without any blank spaces and things like 'tab', 'enter' etc.. then you could first remove those empty spaces using this function:
st.replaceAll("\\s+","")
and then you would just do a string count
String str = "a string";
int length = str.length( );
First of all, why would you use try { } without catch(Exception e)
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("greetings.txt"));
String line = null;
String text = "";
while ((line = reader.readLine()) != null) {
text += line;
}
int c = 0; //count of any character except whitespaces
// or you can use what #Alex wrote
// c = text.replaceAll("\\s+", "").length();
for (int i = 0; i < text.length(); i++) {
if (!Character.isWhitespace(text.charAt(i))) {
c++;
}
}
System.out.println("Number of characters: " +c);
} catch (IOException e) {
System.out.println("File Not Found");
} finally {
if (reader != null) { reader.close();
}
}
Like a similar project I made, this project is reading characters from a txt file, reversing the order of the string and rewriting it to another txt file. But it keeps outputting my exception of "Something went wrong". Can anyone help me fix what is going wrong?
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class ReverseFile
{
public static void main(String[] args) throws IOException
{
try{
String source = args[0];
String target = args[1];
File sourceFile=new File(source);
Scanner content=new Scanner(sourceFile);
PrintWriter pwriter =new PrintWriter(target);
while(content.hasNextLine())
{
String s=content.nextLine();
StringBuffer buffer = new StringBuffer(s);
buffer=buffer.reverse();
String rs=buffer.toString();
pwriter.println(rs);
}
content.close();
pwriter.close();
System.out.println("File is copied successful!");
}
catch(Exception e){
System.out.println("Something went wrong");
}
}
}
So here is the information from the stacktrace:
java.lang.ArrayIndexOutOfBoundsException: 0
at ReverseFile.main(ReverseFile.java:36)
i am not so sure about your environment, and how long the text might be. and i am also not so sure why you need a scanner?
anyway, here's my take on the problem, hope this helps you :)
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Reader;
public class Reverse {
public static void main(String[] args) {
FileInputStream fis = null;
RandomAccessFile raf = null;
// by default, let's use utf-8
String characterEncoding = "utf-8";
// but if you pass an optional 3rd parameter, we use that
if(args.length==3) {
characterEncoding = args[2];
}
try{
// input file
File in = new File(args[0]);
fis = new FileInputStream(in);
// a reader, because it respects character encoding etc
Reader r = new InputStreamReader(fis,characterEncoding);
// an outputfile
File out = new File(args[1]);
// and a random access file of the same size as the input, so we can write in reverse order
raf = new RandomAccessFile(out, "rw");
raf.setLength(in.length());
// a buffer for the chars we want to read
char[] buff = new char[1];
// keep track of the current position (we're going backwards, so we start at the end)
long position = in.length();
// Reader.read will return -1 when it reached the end.
while((r.read(buff))>-1) {
// turn the character into bytes according to the character encoding
Character c = buff[0];
String s = c+"";
byte[] bBuff = s.getBytes(characterEncoding);
// go to the proper position in the random access file
position = position-bBuff.length;
raf.seek(position);
// write one or more bytes for the character
raf.write(bBuff);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// clean up
try {
fis.close();
} catch (Exception e2) {
}
try {
raf.close();
} catch (Exception e2) {
}
}
}
}
You need to specify the filenames(source and target) on command-line, while running the program.
java ReverseFile source.txt target.txt
In your program, you try to read the name of files from command-line as
String source = args[0];
String target = args[1];
So if you do not specify those names there, java tries to access the array args at index 0 and 1 which are empty and you get ArrayIndexOutOfBoundsException.
here is ur error free solution to ur problem,u were using "Scanner" without importing "util"
package.here we go:-----------
import java.io.*;
import java.util.*;
public class ReverseFile
{
public static void main(String[] args) throws IOException
{
try{
File sourceFile=new File(args[0]);
Scanner content=new Scanner(sourceFile);
PrintWriter pwriter =new PrintWriter(args[1]);
while(content.hasNextLine())
{
String s=content.nextLine();
StringBuffer buffer = new StringBuffer(s);
buffer=buffer.reverse();
String rs=buffer.toString();
pwriter.println(rs);
}
content.close();
pwriter.close();
System.out.println("File is copied successful!");
}
catch(Exception e){
System.out.println("Something went wrong");
}
}
}
Just thought of a simple approach.
public class ReadFileReverse {
public int[] readByte(File _file) throws IOException {
FileInputStream source = new FileInputStream(_file);
int currentByte = source.available();
int readCount = 0;
int byteContainer[] = new int[currentByte];
while(readCount < currentByte){
byteContainer[readCount] = source.read();
readCount++;
}
source.close();
return byteContainer;
}
public void printReverse(int[] fileContent){
for(int byt=fileContent.length -1; byt >= 0 ; byt--){
System.out.print((char) fileContent[byt]);
}
}
public static void main(String[] args) throws IOException {
File fileToRead = new File("/README.txt");
ReadFileReverse demo = new ReadFileReverse ();
int[] readBytes = demo.readByte(fileToRead);
demo.printReverse(readBytes);
}
}
Here we are reading a file in string variable, then making a String Builder object to perform reverse operation efficiently, then printing
package com;
import java.io.FileReader;
public class Main {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("D:\\newfile.txt");
String str = "";
int ch;
//reading characters in to string variable
while ((ch = fr.read()) != -1) {
str += Character.toString((char) ch);
}
System.out.println("Original String : " + str);
//converting string variable to String Builder object
StringBuilder sb = new StringBuilder(str);
//reversing the string and printing
System.out.println("Reverse order : " + sb.reverse());
fr.close();
} catch (Exception e) {
System.out.println("error");
}
}
}
Output:
I have a text file that consists of several entries such as:
hello
there
my
name
is
JoeBloggs
How would I read the last five entries in descending order, i.e. from JoeBloggs - there
I currently have code to read the LAST LINE only:
public class TestLastLineRead {
public static void main(String[] args) throws Exception {
FileInputStream in = new FileInputStream(file.txt);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = null, tmp;
while ((tmp = br.readLine()) != null) {
strLine = tmp;
}
String lastLine = strLine;
System.out.println(lastLine);
in.close();
}
}
You can add the lines to a List, e.g. a LinkedList. When the list has more than five lines, remove the first/last.
List<String> lines = new LinkedList<String>();
for(String tmp; (tmp = br.readLine()) != null;)
if (lines.add(tmp) && lines.size() > 5)
lines.remove(0);
One very easy way would be to use the CircularFifoBuffer class from the Apache Commons Collections library. It's basically a list of a fixed size that discards old elements when it's full and you add new ones. So you'd create a CircularFifoBuffer of size 5, then add all the lines to it. At the end, it'd contain just the last five lines of the file.
we can use MemoryMappedFile for printing last 5 lines:
private static void printByMemoryMappedFile(File file) throws FileNotFoundException, IOException{
FileInputStream fileInputStream=new FileInputStream(file);
FileChannel channel=fileInputStream.getChannel();
ByteBuffer buffer=channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
buffer.position((int)channel.size());
int count=0;
StringBuilder builder=new StringBuilder();
for(long i=channel.size()-1;i>=0;i--){
char c=(char)buffer.get((int)i);
builder.append(c);
if(c=='\n'){
if(count==5)break;
count++;
builder.reverse();
System.out.println(builder.toString());
builder=null;
builder=new StringBuilder();
}
}
channel.close();
}
RandomAccessFile to print last 5 lines:
private static void printByRandomAcessFile(File file) throws FileNotFoundException, IOException{
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
int lines = 0;
StringBuilder builder = new StringBuilder();
long length = file.length();
length--;
randomAccessFile.seek(length);
for(long seek = length; seek >= 0; --seek){
randomAccessFile.seek(seek);
char c = (char)randomAccessFile.read();
builder.append(c);
if(c == '\n'){
builder = builder.reverse();
System.out.println(builder.toString());
lines++;
builder = null;
builder = new StringBuilder();
if (lines == 5){
break;
}
}
}
}
Try this code, a list of length 5 is scanned through all the lines, finally the list is reversed. I edited / modified your code, test it to see it's fully working.
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class Test
{
public static void main(String[] args) throws Exception
{
ArrayList<String> bandWidth = new ArrayList<String>();
FileInputStream in = new FileInputStream("file.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String tmp;
while ((tmp = br.readLine()) != null)
{
bandWidth.add(tmp);
if (bandWidth.size() == 6)
bandWidth.remove(0);
}
ArrayList<String> reversedFive = new ArrayList<String>();
for (int i = bandWidth.size() - 1; i >= 0; i--)
reversedFive.add(bandWidth.get(i));
in.close();
}
}
If all it really does have to do is print last 5 lines:
ArrayList<String> lines = new ArrayList<String>();
String tmp="";
while ((tmp = br.readLine()) != null) {
lines.add(tmp);
}
for (int i = lines.size()-5; i < lines.size(); i++) {
System.out.println(lines.get(i-1));
}
First you have to read the file line by line and add each line to a list. Once the file is read completely, you can print each element in the list in reverse order as shown below:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class FileReader {
public static List<String> readFile() throws IOException {
List<String> fileContents = new ArrayList<String>();
FileInputStream fileInputStream = new FileInputStream("C:/Users/compaq/Desktop/file.txt");
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String strLine = null;
while((strLine=bufferedReader.readLine())!=null) {
fileContents.add(strLine);
}
fileInputStream.close();
return fileContents;
}
public static void printFileInReverse(List<String> fileContents, int numberOfLines) {
int counter = 0;
for(int i=(fileContents.size()-1);i>=0;i--) {
if(counter==numberOfLines) { break; }
System.out.println(fileContents.get(i));
counter++;
}
}
public static void main(String[] args) throws IOException {
List<String> fileContents = new ArrayList<String>();
fileContents = FileReader.readFile();
int numberOfLines = 5;// Number of lines that you would like to print from the bottom of your text file.
FileReader.printFileInReverse(fileContents, numberOfLines);
}
}
Try this.
This give for last 5 line.
public static void main(String[] args) throws IOException {
List<String > list =new ArrayList<String>();
FileInputStream in = new FileInputStream("C:/adminconsole.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine ="", tmp;
while ((tmp = br.readLine()) != null){
//strLine =tmp+"\n"+strLine;
list.add(tmp);
}
if(list.size()>5){
for (int i=list.size()-1; i>=(list.size()-5); i--) {
System.out.println(list.get(i));
}
}else{
for (int i=0; i<5; i++) {
System.out.println(list.get(i));
}
}
}
}
Follow This Code To Improve Core Java Logic By Using Collectios.
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Scanner;
public class REVERSE {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
try {
Scanner sc = new Scanner(new FileReader("input.txt"));
while (sc.hasNextLine()) {
al.add(sc.nextLine());
}
System.out.println(al.get(0));
System.out.println(al.get(1));
System.out.println(al.get(2));
System.out.println(al.get(3));
System.out.println(al.get(4));
Collections.reverse(al);
/*
* for (String s : al) { System.out.println(s); }
*/
System.out.println(al.get(0));
System.out.println(al.get(1));
System.out.println(al.get(2));
System.out.println(al.get(3));
System.out.println(al.get(4));
/*
* for (int i = 0; i < al.size(); i++) {
* System.out.println(al.get(i)); }
*/
} catch (FileNotFoundException e) {
}
}
}
Please try this code. It is working fine for me.
public static void main(String[] args)
{
try
{
int numOfLastline = 10;
BufferedReader reader = new BufferedReader(new FileReader("Text.txt"));
int lines = 0;
while (reader.readLine() != null)
lines++;
reader.close();
System.out.println(lines);
String printedLine = null;
List<String> listForString = new ArrayList<String>();
for (int i = lines - 1; i >= (lines - numOfLastline); i--)
{
printedLine = (String) FileUtils.readLines(new File("Text.txt"), "ISO-8859-1").get(i);
System.out.println(printedLine);
listForString.add(printedLine);
}
System.out.println("\n\n============ Printing in Correct order =============\n\n");
Collections.reverse(listForString);
for (int k = 0; k < listForString.size() ; k++)
{
System.out.println(listForString.get(k));
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
Note : Provide your needed last line numbers at numOfLastline and file [instead of this Text.txt].