I am trying to read a .txt file and use each sentence as a name for a team, and at the same time use that name to seek out another .txt file to get its content. All the .txt files are at the root of my assets folder. The first .txt file works fine, I use assetmanager.open
and readLine()
to obtain the string, but when using that string as a parameter to get the second .txt I get a java.io.FileNotFoundException
. However, when calling that same .txt file with a hardcoded String, everything works fine. Upon further inspection I found out that the hardcoded string and the one used as a parameter return false after using the equals()
function on it.
This is the method calling the first.txt
private void loadTeams() {
try {
BufferedReader r = new BufferedReader(new InputStreamReader(assetManager.open("matches.txt")));
String name, bio, trainer;
for(int i = 0; i < 4; i++){
name = r.readLine();
bio = r.readLine();
trainer = r.readLine();
System.out.println(name+", "+bio+", "+trainer);
teams[i] = new Team(name, bio, i, loadPlayers(name), trainer);
}
r.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
using "name" as a parameter for the following method:
private Player[] loadPlayers(String teamName){
Player[] players = new Player[11];
try {
String path = "team_Netherlands.txt"; //works
String path2 = "team_"+teamName+".txt"; //doesn't work?
System.out.println("are "+path+" and " +path2 +" the same? "+path.equals(path2));
BufferedReader r = new BufferedReader(new InputStreamReader(assetManager.open(path2)));
//perform operations on the obtained info
r.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return players;
}
The first sentence in the file is "Netherlands" (without the quotes)
which I think should lead to team_Netherlands.txt
for the path2 variable.
using this will however crash the app. Using the path variable it works just fine. The println confirms that the strings are not equal. (See first sentence of the logcat)
logcat:
05-26 11:18:23.152 2960-2960/com.myname.testapp I/System.out: are team_Netherlands.txt and team_Netherlands.txt the same? false
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: java.io.FileNotFoundException: team_Netherlands.txt
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.content.res.AssetManager.openAsset(Native Method)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.content.res.AssetManager.open(AssetManager.java:354)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.content.res.AssetManager.open(AssetManager.java:328)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at com.myname.testapp.Poule_Activity.load_Players(Poule_Activity.java:144)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at com.myname.testapp.Poule_Activity.load_Teams(Poule_Activity.java:94)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at com.myname.testapp.Poule_Activity.onCreate(Poule_Activity.java:53)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.app.Activity.performCreate(Activity.java:5990)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.app.ActivityThread.access$800(ActivityThread.java:156)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
05-26 11:18:23.152 2960-2960/com.myname.testapp W/System.err: at android.os.Looper.loop(Looper.java:211)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5373)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err: at java.lang.reflect.Method.invoke(Native Method)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err: at java.lang.reflect.Method.invoke(Method.java:372)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
05-26 11:18:23.153 2960-2960/com.myname.testapp W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
Why aren't those strings equal and how to make them equal? (i.e., make the non-hardcoded string equal to the hardcoded one)
To find the duplicate character from the string, we count the occurrence of each character in the string. If count is greater than 1, it implies that a character has a duplicate entry in the string. In above example, the characters highlighted in green are duplicate characters.
To check if two strings have the same characters:Use the sorted() function to sort the two strings. Use the equality operator to compare the results. If the comparison evaluates to True , the two strings have the same characters.
Here is the shortest version (Java 1.5+ required): repeated = new String(new char[n]). replace("\0", s); Where n is the number of times you want to repeat the string and s is the string to repeat.
To check if all characters in a string are the same, compare the string to its first character multiplied by the string's length. If multiplying the first character by the string's length returns True , all characters in the string are the same.
If I execute this code:
public static void main(String[] args) {
load_Players("Netherlands");
}
private static void load_Players(String team_Name) {
String path = "team_Netherlands.txt"; // works
String path2 = "team_" + team_Name + ".txt"; // doesn't work?
System.out.println("are " + path + " and " + path2 + " the same? " + path.equals(path2));
}
All works as expected, so... what's wrong?
As you can see in your log, first Netherlands is not blue, what means parser has found something different.
Suspicious uh?
CHECKS:
When I paste this part of code into my eclipse:
team_Netherlands.txt and team_Netherlands.txt
I get this error when saving:
If I choose option select first character it selects:
System.out.println("team_Netherlands.txt".equals("team_Netherlands.txt"));
↑ this one!!!
So you're passing wrong encoding as you can check with this snippet:
public static void main(String[] args) {
String rightString = "_Netherlands.txt";
String wrongString = "_Netherlands.txt";
System.out.println("WRONG HASH");
System.out.println(rightString.hashCode());
System.out.println("\nRIGHT HASH");
System.out.println(wrongString.hashCode());
System.out.println("\nRIGHT");
printChars(rightString);
System.out.println("\n\nWRONG");
printChars(wrongString);
}
private static void printChars(String s) {
for (Character c : s.toCharArray()) {
System.out.print((int) c + " ");
}
}
OUTPUT:
WRONG HASH
1109617587
RIGHT HASH
-428164238
RIGHT
95 78 101 116 104 101 114 108 97 110 100 115 46 116 120 116
WRONG
95 65279 78 101 116 104 101 114 108 97 110 100 115 46 116 120 116
// ↑ here!!
SOLUTION's: (source)
BOMInputStream
from Apache IO CommonsHandle manually (fast easy way):
private static String clean(String s) throws Exception {
InputStream is = new ByteArrayInputStream(s.getBytes());
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
// BOM marker will only appear on the very beginning
br.mark(4);
if ('\ufeff' != br.read())
br.reset(); // not the BOM marker
return br.readLine();
}
}
TEST IT!:
public static void main(String[] args) throws Exception {
String rightString = "Netherlands.txt";
String wrongString = "Netherlands.txt";
System.out.println("\nCOMPARE");
System.out.println(rightString.equals(wrongString));
System.out.println("\nCLEAN COMPARE");
System.out.println(clean(rightString).equals(clean(wrongString)));
System.out.println("\nRIGHT");
printChars(clean(rightString));
System.out.println("\n\nWRONG");
printChars(clean(wrongString));
}
private static String clean(String s) throws Exception {
InputStream is = new ByteArrayInputStream(s.getBytes());
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
// BOM marker will only appear on the very beginning
br.mark(4);
if ('\ufeff' != br.read())
br.reset(); // not the BOM marker
return br.readLine();
}
}
private static void printChars(String s) {
for (Character c : s.toCharArray()) {
System.out.print((int) c + " ");
}
}
OUTPUT:
COMPARE
false
CLEAN COMPARE
true
RIGHT
78 101 116 104 101 114 108 97 110 100 115 46 116 120 116
WRONG
78 101 116 104 101 114 108 97 110 100 115 46 116 120 116
The team_name
you read from file contains UTF-8 byte order mark octets in front
ef bb bf
and they are not visible as such in log output.
Either save the files without BOM, or remove the BOM in your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With