Java - Won't read out File content - java

I have a .txt file with, for example, this content:
variable1="hello";
variable2="bye";
testing3="parameter";
whatisthis4="hello";
var5="exampletext";
example=3;
wellthen=8;
---
It read in the file, line by line, fine until I added a way of saving the data.
This whole code plus another reader (with other variable names of course) is wrapped in a try-catch statement.
String path_playlist = new File("").getAbsolutePath();
String fileName_playlist = path_playlist
+ "/src/dancefusion/game/playlist.txt";
FileReader fr_playlist = new FileReader(fileName_playlist);
BufferedReader br_playlist = new BufferedReader(fr_playlist);
int track_counter = track_sum*9;
String trackinfos[] = new String[track_counter];
while(track_counter < 0)
{
System.out.println("linecount="+track_counter);
trackinfos[track_counter] = br_playlist.readLine();
System.out.println(trackinfos[track_counter]);
track_counter--;
}
System.out.println(Arrays.toString(trackinfos));
In this example track_sum equals 1.
The while loop should read in the file one line at a time but only reads null's:
[null, null, null, null, null, null, null, null, null]
Update 1:
The while-condition was set up the wrong way... thanks!
The corrected version:
while(track_counter < 0)
However, now it gives me an exception with an "ArrayOutOfBounds: 9".
Any guesses?
Final Update:
As mentioned by #GiorgiMoniava, I just needed to reduce track_counter by one before starting to read in as in Java arrays begin with 0, thanks!
int track_counter = track_sum*8;
String trackinfos[] = new String[track_counter];
track_counter--;
while(track_counter >= 0)
{
System.out.println("linecount="+track_counter);
trackinfos[track_counter] = br_playlist.readLine();
System.out.println(trackinfos[track_counter]);
track_counter--;
}
Maybe one of you can figure out what I did wrong...
Of course I can deliver more information/code if needed!
Thanks in advance!

This looks weird
while(track_counter < 0)
Are you sure loop is ever entered in? It is my guess (from your output) that track_counter is 9.
About your array out of bounds exception: if you create array of size N you can only access it using indexes: [0, N-1]

try this
while(track_counter > 0)
{
System.out.println("linecount="+track_counter);
track_counter--;
trackinfos[track_counter] = br_playlist.readLine();
System.out.println(trackinfos[track_counter]);
}

Related

SNMP Listener can not read trap from OIDs that are entries in a table

I have written a SNMP listener in Java using the TNM4J library which uses the SNMP4J library.
The listener is able to read received traps, except for traps that appear to be indexed in a table.
The listener is listening to traps from an Ericsson object, which means I am using the ERICSSON-ALARM-MIB and the MIB imports it needs. The trap I am receiving is the eriAlarmActiveManagedObject with OID .1.3.6.1.4.1.193.183.4.1.3.5.1.5, but I also tested it locally with the other traps in the table and the same error occurs
If one looks at https://mibs.observium.org/mib/ERICSSON-ALARM-MIB/ :
All the traps that are from a table like this can not be read by the listener.
It gives an index out of bound exception from a extractIndexes method in MibbleIndexExtractor.java in the TNM4J library.
#Override
public IndexDescriptor[] extractIndexes(String instanceOid) {
String oid = symbol.getValue().toString();
String suboid = instanceOid.substring(oid.length() + 1);
int[] components = oidToArray(suboid);
int offset = 0;
IndexDescriptor[] descriptors = new IndexDescriptor[indexes.length];
for (int i = 0; i < indexes.length; i++) {
SnmpIndex index = indexes[i];
MibValueSymbol indexSymbol = symbol.getMib().getSymbolByOid(index.getValue().toString());
MibType indexType = ((SnmpObjectType) indexSymbol.getType()).getSyntax();
int length = fixedLength(indexType);
boolean implied = length != -1 || index.isImplied();
if (length == -1) {
length = variableLength(indexType, components, offset, index.isImplied());
}
int[] encoded = new int[length];
System.arraycopy(components, offset, encoded, 0, length);
descriptors[i] = new MibbleIndexDescriptor(indexSymbol, encoded, implied);
offset += length;
}
return descriptors;
}
I have debugged it and this happens because the oid String and instanceOid String are identical which of course causes an exception where the suboid String is being created.
However on all other traps it never calls this extractIndexes method, but just works finely and prints out the trap and oid name correctly.
Any suggestion on how to fix this issue?
After being in contact with the developer of TNM4J he made some fixes to his library.
After that the Ericsson oids was being correctly translated. There was a few missing translations from oids, which was because of the loading order of the MIBs.
Re-adjusting these made it work.
For anyone interested the troubleshooting process with the developer can view it here:
https://github.com/soulwing/tnm4j/issues/9

How to JGit blame a file before commit?

Context: My merge ran into conflicts and I have a file like this example:
Foo.txt (merged)
1
<<<<<< HEAD
2-master
======
2-side
>>>>>> df803849788fde47965b3dc8f07f07d48320ea9c
3
Question: In order to get the developers who actually changed the conflicting lines, how to blame result file (above) prior to the commit? It works for git blame Foo.txt
Problem: I tried to do the following, but the blame is null inside the loop.
MergeResult m = runMerge(aScenario);
BlameCommand blamer = new BlameCommand(git.getRepository());
BufferedReader br = new BufferedReader(new FileReader(new File(mergedfilepath)));
BlameResult blame = blamer.setFilePath(mergedfilepath).call();
for (int i = 0; (line= br.readLine())!=null ; i++) {
// the blame at this point is null.
PersonIdent person = blame.getSourceAuthor(i);
System.out.println(person.getName() + ": "+ line);
}
I think the source of the traversal should be the result contents.
Starting from there you can loop over the changed regions and ask for the author. For example:
BlameResult blameResult = git.blame().setFilePath( ... ).call();
int size = blameResult.getResultContents().size();
for( int i = 0; i < size; i++ ) {
System.out.println( blameResult.getSourceAuthor( i ) );
}
At least for lines added to the work directory version of the file, an author named Not Committed Yet is returned.
However, your code should be prepared cope with getSourceAuthor() returning null. The JavaDoc states that the return value may be null.

Weird BufferedReader behavior for a huge file

I am getting a very weird error. So, my program read a csv file.
Whenever it comes to this line:
"275081";"cernusco astreet, milan, italy";NULL
I get an error:
In the debug screen, I see that the BufferedReader read only
"275081";"cernusco as
That is a part of the line. But, it should read all of the line.
What bugs me the most is when I simply remove that line out of the csv file, the bug disappear! The program runs without any problem. I can remove the line, maybe it is a bad input or whatever; but, I want to understand why I am having this problem.
For better understanding, I will include a part of my code here:
reader = new BufferedReader(new FileReader(userFile));
reader.readLine(); // skip first line
while ((line = reader.readLine()) != null) {
String[] fields = line.split("\";\"");
int id = Integer.parseInt(stripPunctionMark(fields[0]));
String location = fields[1];
if (location.contains("\";")) { // When there is no age. The data is represented as "location";NULL. We cannot split for ";" here. So check for "; and split.
location = location.split("\";")[0];
System.out.printf("Added %d at %s\n", id, location);
people.put(id, new Person(id, location));
numberOfPeople++;
}
else {
int age = Integer.parseInt(stripPunctionMark(fields[2]));
people.put(id, new Person(id, location, age));
System.out.printf("Added %d at: %s age: %d \n", id, location, age);
numberOfPeople++;
}
Also, you can find the csv file here or here is a short version of the part that I encountered the error:
"275078";"el paso, texas, usa";"62"
"275079";"istanbul, eurasia, turkey";"26"
"275080";"madrid, n/a, spain";"29"
"275081";"cernusco astreet, milan, italy";NULL
"275082";"hacienda heights, california, usa";"16"
"275083";"cedar rapids, iowa, usa";"22"
This has nothing whatsoever to do with BufferedReader. It doesn't even appear in the stack trace.
It has to do with your failure to check the result and length of the array returned by String.split(). Instead you are just assuming the input is well-formed, with at least three columns in each row, and you have no defences if it isn't.

Java: populating Scanner with default value on Scanner.nextLine();

I am writing a java program that runs a loop and keeps asking the user for input. The program then does a bunch of things with the string, and asks for another string and repeats.
The issue is that many strings are very similar, so i would like to populate the prompt with the input from the last time in the loop. For instance: If the user enters a value as follows:
Enter the SKU Number: APE-6603/A
... Then the next time it asks for an SKU, it will wait till the user presses enter as normal, but be ready with the last value before the user even types anything:
Enter the SKU Number: APE-6603/A
... And the user can make simple changes very fast like replace the /A with /B and press enter! If the string that holds the user input is called "lookFor", is there a way to populate the prompt with this value in Java? It would be VERY useful!
Thanks!
After discussing this idea with a few people, it seems that what i want is not possible. The way of input is too simple to allow something like this.
My only possible solutions involve not running this from my IDE. I can either elect to use my application, or change the application into a GUI based applet. Running from the console will open up the "Press up" option, as suggested by rchirino, and using a GUI would let the value entered sit there for editing later.
If anyone is looking to do what i posted above, the answer is "Java cant do it!". Sorry. :)
You might want to try something like this:
public String promptandgetWithShowDefault(String prompt, String supplied) {
String prmpt = prompt + " (press Enter for \"" + supplied + "\"):";
String tmpch = null;
System.out.print(prmpt);
tmpch = scanner.nextLine().trim();
if (tmpch == null || tmpch.equals("")) {
return supplied;
} else {
return tmpch;
}
}
If the goal is to get a simple binar answer from the user like:
Would you like to do that? ( y / n ) y
then the empty string returned by the user, in the answer from Dmv, will do the trick, except that when the user types "n" or attempts to delete the trailing "y", it won't disappear, so it would then be clearer to write the prompt like:
Would you like to do that? ( [ y ] / n )
But when the goal is to get a long string, like the original question or a file path for instance, that the user can edit to correct a typo or not to overwrite previous file .... then you definitely need something else which doesn't seem to be available in Java.
Well do it in C then!!! with the help of libreadline...
it's probably possible, easier and more portable to do the same trick in Python, but I have no idea how to code in Python.
Here is a simple Java MRE to illustrate it:
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
public class Main
{
public static void main(String[] args)
{
String path = System.getProperty("user.home") + File.separatorChar + "Documents";
File file = null;
do {
path = askForString("Enter the filepath to open:", path );
if ( ( path == null) || ( path.isBlank())) break;
file = new File( path );
} while ( ! file.exists() );
System.out.println("Openning " + path + "....");
// ......
}
public static String askForString( String message, String defaultString)
{
String response = null;
System.out.println( message);
// any extra String in cmd[] will be added in readline history
String[] cmd = { "/path/to/executable/ask4stringWdefault", defaultString};
try
{
ProcessBuilder pb = new ProcessBuilder(cmd);
// Make sure the subprocess can print on console and capture keyboard events
pb.redirectInput(ProcessBuilder.Redirect.INHERIT);
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
Process p = pb.start();
BufferedReader stderrBuffer = new BufferedReader(new InputStreamReader(p.getErrorStream()));
int retcode= p.waitFor();
if ( retcode != 0)
{
System.err.println("The process terminated with error code: " + retcode + "\n" + stderrBuffer.readLine());
return null;
}
response = stderrBuffer.readLine();
} catch( Exception e) {
e.printStackTrace();
}
return response;
}
}
To build the executable "ask4stringWdefault" you need first to get the GNU Readline Library utility and compile it, ideally cross-compile for any platform Java supports, to get a static library that you will link while compiling ( or cross-compiling ) the following C script:
#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
const char *defstr;
int prefill(const char *txt, int i);
int main(int argc, const char * argv[])
{
if ( argc < 2)
{
fprintf(stderr, "You must provide a default value\n");
return -1;
} else if ( argc > 2) {
// * optional extra values can be passed to populate history * //
if ( argc > 255) argc = 255;
for ( unsigned char i=0; i < argc; i++)
{
add_history(argv[i]);
}
}
defstr = argv[1];
char *cbuffer;
rl_startup_hook = prefill;
if ((cbuffer = readline(NULL)) == NULL) /* if the user sends EOF, readline will return NULL */
return 1;
fprintf( stderr, "%s\n", cbuffer);
free(cbuffer);
return 0;
}
int prefill(const char *t, int i)
{
rl_insert_text(defstr);
return 0;
}
The result is printed on stderr as it is the only stream that Java can keep track of, stdout and stdin being under the control of the executable subprocess itself.
It works fine on a Mac with arm64 architecture, using Eclipse you can't actually edit the default provided, any character typed at the prompt will be append to default string, but just hitting return will send unchanged default value back, which can be enough for basic testing.
I think I understand what you want to do, but it's rather simple. If your program is a console application (command-line), which I'll assume, then you just need to press the UP key to populate the prompt with the last typed characters.
If you're working with GUI elements then you can check the API documentation for the particular class of object you're using and check out it's fields.
Hope this helps!

labeling an unlabeled instance in Weka(java code)

I am beginner in java and Weka tool, I want to use Logitboost algorithm with DecisionStump as weak learner in my java code, but I don't know how do this work. I create a vector with six feature(without label feature) and I want feed it into logitboost for labeling and probability of its assignment. Labels are 1 or -1 and train/test data is in an arff file.This is my code, but algorithm always return 0 !
Thanks
double candidate_similarity(ha_nodes ha , WeightMatrix[][] wm , LogitBoost lgb ,ArrayList<Attribute> atts){
LogitBoost lgb = new LogitBoost();
lgb.buildClassifier(newdata);//newdata is an arff file with some labeled data
Evaluation eval = new Evaluation(newdata);
eval.crossValidateModel(lgb, newdata, 10, new Random(1));
try {
feature_vector[0] = IP_sim(Main.a_new.dip, ha.candidate.dip_cand);
feature_vector[1] = IP_sim(Main.a_new.sip, ha.candidate.sip_cand);
feature_vector[2] = IP_s_d_sim(Main.a_new.sip, ha);
feature_vector[3] = Dport_sim(Main.a_new.dport, ha);
freq_weight(Main.a_new.Atype, ha, freq_avg, weight_avg , wm);
feature_vector[4] = weight_avg;
feature_vector[5] = freq_avg;
double[] values = new double[]{feature_vector[0],feature_vector[1],feature_vector[2],feature_vector[3],feature_vector[4],feature_vector[5]};
DenseInstance newInst = new DenseInstance(1.0,values);
Instances dataUnlabeled = new Instances("TestInstances", atts, 0);
dataUnlabeled.add(newInst);
dataUnlabeled.setClassIndex(dataUnlabeled.numAttributes() - 1);
double clslable = lgb.classifyInstance(inst);
} catch (Exception ex) {
//Logger.getLogger(Module2.class.getName()).log(Level.SEVERE, null, ex);
}
return clslable;}
Where did this newdata come from? you need to load the file properly to get a correct classification, use this class to load features from the file:
http://weka.sourceforge.net/doc/weka/core/converters/ArffLoader.html
I'm not posting an example code because I use weka with MATLAB, so I dont have examples in Java.

Categories