I want to read a file line by line in Java. Each line is added as an item to an array. Problem is that, I have to create the array based on the number of lines in the file while I am reading line by line.
I can use two separate while loops one for counting and then creating the array and then adding items. But it is not efficient for large files.
try (BufferedReader br = new BufferedReader(new FileReader(convertedFile))) {
String line = "";
int maxRows = 0;
while ((line = br.readLine()) != null) {
String [] str = line.split(" ");
maxColumns = str.length;
theRows[ maxRows ] = new OneRow( maxColumns ); // ERROR
theRows[ maxRows ].add( str );
++maxRows;
}
}
catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
catch (IOException e) {
System.out.println(e.getMessage());
}
Consider private OneRow [] theRows; and OneRow is defined as String []. the file looks like
Item1 Item2 Item3 ...
2,3 4n 2.2n
3,21 AF AF
...
You can't resize an array. Use the ArrayList class instead:
private ArrayList<OneRow> theRows;
...
theRows.add(new OneRow(maxColumns));
Check ArrayList. ArrayList is resisable array.And is equivalent to C++ Vector.
try (BufferedReader br = new BufferedReader(new FileReader(convertedFile)))
{
List<String> str= new ArrayList<>();
String line = "";
while ((line = br.readLine()) != null) {
str.add(line.split(" "));
}
}
catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e){
System.out.println(e.getMessage());
}
I would consider using the ArrayList data structure. If you are unfamiliar with how ArrayLists work I would read up on the documentation.
Related
I have a text file with state-city values:-
These are the contents in my file:-
Madhya Pradesh-Bhopal
Goa-Bicholim
Andhra Pradesh-Guntur
I want to split the state and the city... Here is my code
FileInputStream fis= new FileInputStream("StateCityDetails.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int h=0;
String s;
String[] str=null;
byte[] b= new byte[1024];
while((h=bis.read(b))!=-1){
s= new String(b,0,h);
str= s.split("-");
}
for(int i=0; i<str.length;i++){
System.out.println(str[1]); ------> the value at 1 is Bhopal Goa
}
}
Also I have a space between Madhya Pradesh..
So i want to Remove spaces between the states in the file and also split the state and city and obtain this result:-
str[0]----> MadhyaPradesh
str[1]----> Bhopal
str[2]-----> Goa
str[3]----->Bicholim
Please Help..Thank you in advance :)
I would use a BufferedReader here, rather than the way you are doing it. The code snippet below reads each line, split on hyphen (-), and removes all whitespace from each part. Each component is entered into a list, in left to right (and top to bottom) order. The list is converted to an array at the end in case you need this.
List<String> names = new ArrayList<String>();
BufferedReader br = null;
try {
String currLine;
br = new BufferedReader(new FileReader("StateCityDetails.txt"));
while ((currLine = br.readLine()) != null) {
String[] parts = currLine.split("-");
for (int i=0; i < parts.length; ++i) {
names.add(parts[i].replaceAll(" ", ""));
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
// convert the List to an array of String (if you require it)
String[] nameArr = new String[names.size()];
nameArr = names.toArray(nameArr);
// print out result
for (String val : nameArr) {
System.out.println(val);
}
If I have a file that contains for example:
results1: 2, 4, 5, 6, 7, 8, 9
results2: 5, 3, 7, 2, 8, 5, 2
I want to add the integers from each line to a array. One array
for each line. How can I do this with code that does only read the integers?
Here's what I got this far
String data = null;
try {
Scanner in = new Scanner(new File(myFile));
while (in.hasNextLine()) {
data = in.nextLine();
numbers.add(data);
}
in.close();
} catch (Exception e) {
}
Easy.
One line per array, not two as you have it. New line after each one.
Read each line as a String, discard the leading "resultsX:", and split what remains at a delimiter of your choosing (e.g. comma). Parse each into an integer and add it to a List.
I don't think that leading "results1: " is adding any value. Why do you have that?
public static void main(String[] args) throws IOException {
BufferedReader reader=null;
try {
reader = new BufferedReader(new FileReader(new File("PATH TO FILE")));
// Only works if File allways contains at least two lines ... all lines after the second
// will be ignored
System.out.println(String.format("Array 1 : %s", Arrays.toString(stringArray2IntArray(readNextLine(reader)))));
System.out.println(String.format("Array 2 : %s", Arrays.toString(stringArray2IntArray(readNextLine(reader)))));
} finally {
if (reader!=null) {
reader.close();
}
}
}
private static Integer[] stringArray2IntArray(String[] numStrings) {
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < numStrings.length; i++) {
result.add(Integer.parseInt(numStrings[i].trim()));
}
return result.toArray(new Integer[numStrings.length]);
}
private static String[] readNextLine(BufferedReader reader) throws IOException {
return reader.readLine().split(":")[1].split(",");
}
Assuming you have an input file, like this:
2,4,5,6,7,8,9
5,3,7,2,8,5,2
here is a code snippet to load it:
String firstLine = "";
String secondLine = "";
File file = new File("path/to/file");
try {
BufferedReader br = new BufferedReader(new FileReader(file));
firstLine = br.readLine();
secondLine = br.readLine();
} catch(Exception e){
e.printStackTrace();
}
String[] firstResult = firstLine.split(",");
String[] secondResult = secondLine.split(",");
int[] firstIntegers = new int[firstResult.length];
for(int i = 0; i <= firstResult.length ; i++){
firstIntegers[i] = Integer.parseInt(firstResult[i]);
}
int[] secondIntegers = new int[secondResult.length];
for(int i = 0; i <= secondResult.length ; i++){
firstIntegers[i] = Integer.parseInt(secondResult[i]);
}
Open the file with a BufferedReader br and then read it line by line.
Store each line in an int array and add all those int arrays to a list. At the end, this list will contain all the int arrays that we wanted, so iterate this list to do whatever you want to do next.
String filePath = "/path/to/file";
BufferedReader br = null;
List<Integer[]> arrays = new ArrayList<>(); //this contains all the arrays that you want
try {
br = new BufferedReader(new FileReader(filePath));
String line = null;
while ((line = br.readLine()) != null) {
line = line.substring(line.indexOf(":")+2); //this starts the line from the first number
String[] stringArray = line.split(", ");
Integer[] array = new Integer[stringArray.length];
for (int i = 0; i < stringArray.length; ++i) {
array[i] = Integer.parseInt(stringArray[i]);
}
arrays.add(array);
}
} catch (FileNotFoundException ex) {
System.err.println(ex);
} catch (IOException ex) {
System.err.println(ex);
} finally {
try {
br.close();
} catch (Exception ex) {
System.err.println(ex);
}
}
Since ArrayLists keep insertion order, then, e.g., arrays.get(3) will give you the array of the fourth line (if there is such a line) and arrays.size() will give you the number of lines (i.e., int arrays) that are stored.
I have two files one contains data and another contains the string.
My target is to read the file containing string and see if that string exist in data file and delete that whole row.
Sample data would be :
Data file :
Name='Raj' Age='25' Location='India'
Name='Suresh' Age='26' Location='India'
String file contain :
Raj
So when it parse the data file it should delete the first line from data file.
This is not so difficult, and you haven't post what you have tried. However I am posting a solution for your reference. You can modify/optimize it as per your requirement.
1. First Create a method -
private List<String> getFileContentList(String filePath) {
List<String> list = new ArrayList<String>();
try {
String line;
BufferedReader br = new BufferedReader(new FileReader(filePath));
while ((line = br.readLine()) != null) {
list.add(line);
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
2. Now do something like below -
List<String> dataList = getFileContentList("C:/DataFile.txt");
List<String> keyList = getFileContentList("C:/KeyFile.txt");
for (String string1 : keyList) {
for (int i = 0; i < dataList.size(); i++) {
if(dataList.get(i).contains(string1)) {
dataList.remove(i);
}
}
}
FileWriter fw;
try {
fw = new FileWriter("C:/DataFile.txt");
BufferedWriter bw = new BufferedWriter(fw);
for (String string : dataList) {
bw.write(string);
bw.newLine();
}
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
I'm trying to read a large text file in the form of:
datadfqsjmqfqs+dataqfsdqjsdgjheqf+qsdfklmhvqziolkdsfnqsdfmqdsnfqsdf+qsjfqsdfmsqdjkgfqdsfqdfsqdfqdfssdqdsfqdfsqdsfqdfsqdfs+qsfddkmgqjshfdfhsqdflmlkqsdfqdqdf+
I want to read this string in the text file as one big java String. Is this possible? I know the use of the split method.
It worked to read it line by line, but what I really need is to split this long text-string at the '+' sign. Afterwards I want to store it as an array, arraylist, list,...
Can anyone help me with this? Because every information on the internet is just about reading a file line by line.
Thanks in advance!
String inpStr = "datadfqsjmqfqs+dataqfsdqjsdgjheqf+qsdfklmhvqziolkdsfnqsdfmqdsnfqsdf+qsjfqsdfmsqdjkgfqdsfqdfsqdfqdfssdqdsfqdfsqdsfqdfsqdfs+qsfddkmgqjshfdfhsqdflmlkqsdfqdqdf+";
String[] inpStrArr = inpStr.split("+");
Hope this is what you need.
You can read file using BufferedReader or any IO-classes.suppose you have that String in testing.txt file then by reading each line from file you can split it by separator (+). and iterate over array and print.
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader("C:\\testing.txt"));//file name with path
while ((sCurrentLine = br.readLine()) != null) {
String[] strArr = sCurrentLine.split("\\+");
for(String str:strArr){
System.out.println(str);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
It seems to me like your problem is that you don't want to read the file line by line. So instead, try reading it in parts (say 20 characters each time and building your string):
char[] c = new char[20]; //best to save 20 as a final static somewhere
ArrayList<String> strings = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new FileReader(filename));
while (br.read(c) == 20) {
String str = new String(c);
if (str.contains("+") {
String[] parts = str.split("\\+");
sb.append(parts[0]);
strings.add(sb.toString());
//init new StringBuilder:
sb = new StringBuilder();
sb.add(parts[1]);
} else {
sb.append(str);
}
}
You should be able to get a String of length Integer.MAX_VALUE (always 2147483647 (231 - 1) by the Java specification, the maximum size of an array, which the String class uses for internal storage) or half your maximum heap size (since each character is two bytes), whichever is smaller
How many characters can a Java String have?
Try this one:
private static void readLongString(File file){
ArrayList<String> list = new ArrayList<String>();
StringBuilder builder = new StringBuilder();
int r;
try{
InputStream in = new FileInputStream(file);
Reader reader = new InputStreamReader(in);
while ((r = reader.read()) != -1) {
if(r=='+'){
list.add(builder.toString());
builder = new StringBuilder();
}
builder.append(r);
}
}catch (IOException ex){
ex.printStackTrace();
}
for(String a: list){
System.out.println(a);
}
}
Here is one way, caveat being you can't load more than the max int size (roughly one GB)
FileReader fr=null;
try {
File f=new File("your_file_path");
fr=new FileReader(f);
char[] chars=new char[(int)f.length()];
fr.read(chars);
String s=new String(chars);
//parse your string here
} catch (Exception e) {
e.printStackTrace();
}finally {
if(fr!=null){
try {
fr.close();
} catch (IOException e) {
}
}
}
I'm trying to read in a .csv file containing node data (p-values mostly) into my progam, but in doing so I have to convert them from strings into doubles. Here's the method for it:
public ArrayList<Node> getCSVFile(String file){
String csvFile = file;
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
ArrayList<Node> nL = new ArrayList<Node>();
int count = 0;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] node = line.split(cvsSplitBy);
double pVal = Double.parseDouble(node[4]);
nL.add(new Node(count, node[0], pVal));
count++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return nL;
}
The object Node is parameterized as Node(int, String, double), but the first line of the file I'm trying to convert is a column name, and I'm not entirely sure of the nature of the entries after that. Here's a look at the start of the file:
GENE,COMMON,gal1RGexp,gal4RGexp,gal80Rexp,gal1RGsig,gal4RGsig,gal80Rsig
YHR051W,COX6,-0.034,0.111,-0.304,3.75720e-01,1.56240e-02,7.91340e-06
YHR124W,NDT80,-0.090,0.007,-0.348,2.71460e-01,9.64330e-01,3.44760e-01
YKL181W,PRS1,-0.167,-0.233,0.112,6.27120e-03,7.89400e-04,1.44060e-01
YGR072W,UPF3,0.245,-0.471,0.787,4.10450e-04,7.51780e-04,1.37130e-05
YHL020C,OPI1,0.174,-0.015,0.151,1.40160e-04,7.19120e-01,1.53950e-02
YGR145W,YGR145W,0.387,-0.577,-0.088,5.37920e-03,8.27330e-03,7.64180e-01
YGL041C,YGL041C,0.285,-0.086,0.103,4.46050e-04,4.50790e-01,7.03040e-01
YGR218W,CRM1,-0.018,-0.001,-0.018,6.13810e-01,9.79400e-01,8.09690e-01
YOR202W,HIS3,-0.432,-0.710,0.239,1.09790e-02,1.79790e-04,5.48950e-03
YCR005C,CIT2,0.085,0.392,0.464,4.18980e-02,1.53050e-06,2.74360e-06
YER187W,KHS1,0.159,0.139,-0.045,8.51260e-04,4.17830e-03,6.18020e-01
YBR026C,YBR026C,0.276,0.189,0.291,3.63320e-05,6.15230e-04,1.24430e-03
YMR244W,YMR244W,0.078,-0.239,-0.072,5.76050e-01,3.55240e-01,8.85690e-01
Etc etc..
So the code creates nodes for each line based on the first and fifth columns, as well as a unique counter. However how can I skip the first line that just has the column names? I'm a little hesitant to simply have something skipping all first lines in all files, as not all files read may have a string as a first line. Even then, are the following lines suitable for being converted to doubles?
Thanks!
What about skipping lines when parsing the double is not possible?
Like this:
public ArrayList<Node> getCSVFile(String file){
String csvFile = file;
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
ArrayList<Node> nL = new ArrayList<Node>();
int count = 0;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] node = line.split(cvsSplitBy);
double pVal;
try {
pVal = Double.parseDouble(node[4]);
} catch (NumberFormatException e) {
continue; // Skip this line if this isn't a double
}
nL.add(new Node(count, node[0], pVal));
count++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return nL;
}
Change the signature of your existing method to:
public ArrayList<Node> getCSVFile(String file, int startAt){
and use startAt inside of your read loop to control how many lines are skipped. I'd recommend creating a default method that returns all lines:
public ArrayList<Node> getCSVFile(String file){
return getCSVFile(file, 0);
}
Alternatively this could be a boolean if you know that you'll either want to skip the first line or none at all.
As for the second part of your question, many of those strings will not be parseable. You may want to read this. But I'm not sure how you expect to parse or use a value like 'YHR051W' (since you said you wanted the first column).