Java - String.contains() behaves oddly - java

this snippet of code works fine on my development machine (Windows 7 installed on VirtualBox jre 8 using Netbeans IDE), but on another machine (Windows 7 jre 8) always returns true.
It should only find files with a name like "town_house.html" instead it always returns true for every file in the folder.Running the jar file from prompt I don't get any exceptions.
Maybe it's just a trivial error I usually program in C/C++ ... any idea?
for(File f : files)
{
if(f.toString().contains("_") &&
f.toString().contains(".html")){
System.out.print("Processing file: " + f.getName()+ "\n");
String[] fileSplit = f.getName().split("_");
towns.add(fileSplit[0]);
}
}
Thanks in advance

You are checking toString() instead of getName() - maybe the directory path contains an underscore.
Try this instead (note also simplified test):
for(File f : files) {
if (f.getName().matches(".*_.*\\.html")) {
System.out.print("Processing file: " + f.getName()+ "\n");
String[] fileSplit = f.getName().split("_");
towns.add(fileSplit[0]);
}
}

Related

How use openalpr in java project

I want to use openalpr in my java project. What must I include to use the API? What libs must be imported in project properties in Eclipse or Netbeans?
I found the solution
Download openalpr binaries
https://github.com/openalpr/openalpr/releases
Install and configure jdk (java and javac path)
Compile openalpr java source code, start java_test.bat file
Start main.java
java -classpath java Main "us" "openalpr.conf" "runtime_data" "samples/us-1.jpg"
Copy the native libs (DLLs for windows) into the exec dir
Copy the java classes into your project (dir: /src/main/java)
Get started with:
`
Alpr alpr = new Alpr("us", "/path/to/openalpr.conf", "/path/to/runtime_data");
// Set top N candidates returned to 20
alpr.setTopN(20);
// Set pattern to Maryland
alpr.setDefaultRegion("md");
AlprResults results = alpr.recognize("/path/to/image.jpg");
System.out.format(" %-15s%-8s\n", "Plate Number", "Confidence");
for (AlprPlateResult result : results.getPlates())
{
for (AlprPlate plate : result.getTopNPlates()) {
if (plate.isMatchesTemplate())
System.out.print(" * ");
else
System.out.print(" - ");
System.out.format("%-15s%-8f\n", plate.getCharacters(), plate.getOverallConfidence());
}
}
(Source: http://doc.openalpr.com/bindings.html#java)

Is this a bug in java jdk?

When I got a java.lang.File class with the code File file = new File("e:/");, of course I got a File class represented the e:\ directory.
But if I got a File class with code File file = new File("e:"); and I just in the drive E:, then I got a File class represented current directory.
Assume I'm in directory E:\dir\, And this directory have a file named Test.java.
It's content is:
import java.io.File;
public class Test {
public static void main(String[] args) {
File file = new File("e:");
File[] files = file.listFiles();
for(File f: files){
System.out.println(f + " " + f.exists());
}
}
}
Open the cmd tool and navigate to the directory e:\dir, execute the following command in it:
E:\dir> javac Test.java
E:\dir> java Test
I got:
e:\Test.class false
e:\Test.java false
Is this a java jdk bug?
Additional information from #JimGarrison:
I ran this code
public class Foo3
{
public static void main(String[] args) throws Exception
{
File f = new File("D:");
System.out.println(f.getCanonicalPath());
for (File x : f.listFiles())
System.out.println(x + " " + x.getCanonicalPath() + " " + x.getAbsolutePath() + " " + x.exists() + " " + x.getAbsoluteFile().exists());
}
}
in Eclipse (which lives on my D: drive) and got the following output:
D:\dev\src\pdxep
D:\.classpath D:\dev\src\pdxep\.classpath D:\dev\src\pdxep\.classpath false true
D:\.project D:\dev\src\pdxep\.project D:\dev\src\pdxep\.project false true
D:\.settings D:\dev\src\pdxep\.settings D:\dev\src\pdxep\.settings false true
D:\gallery D:\dev\src\pdxep\gallery D:\dev\src\pdxep\gallery false true
D:\pom.xml D:\dev\src\pdxep\pom.xml D:\dev\src\pdxep\pom.xml false true
D:\src D:\dev\src\pdxep\src D:\dev\src\pdxep\src false true
D:\target D:\dev\src\pdxep\target D:\dev\src\pdxep\target false true
Which confirms there's something funny going on.
Java Bug 8130462 seems to be related as it has to do with relative vs absolute paths specifically in Windows.
It's not a bug.
E:/ means that you specify both a drive and a directory
E: means you only specify a drive, the directory is left to the default value.
Note: Now what people think of as current directory is actually default directory. i.e. what is applied by default when none is specified.
It's just the same if you don't specify the drive at all, the default (current default) will apply.
This is the way it works on most File Systems.
The first part about getting a File representing the current working directory with code File file = new File("e:"); is not a bug. It is a Windows "drive relative path". That is, a path relative to the current working directory in the specified drive. (Yes, Windows have a different working director per drive)
The issue is that Java wrongly adds a \ after the drive-letter in the path which makes the path look like an absolute path, and wrongly returns false on file.exists() probably because of that.
However, Java correctly resolves the canonical-path and absolute-path and correctly returns true on x.getAbsoluteFile().exists(). Java also correctly returns the contents of the CWD in file.listFiles() as you noticed in your example code.
I found an old bug in the database which JDK-5066567 about this or at least very similar to this. It was created in 2004 and set to "In progress" 2013 and the current Assignee is "Inactive" so I don't think we will see any fix for this soon, if ever.
So to answer you question, I would say yes, it is a bug.
However, it seems like it is better handled in java.nio.file.Path. So if it is possible to use the java.nio.file.* package instead in your use case, it might be a acceptable workaround.

why does Files.probeContentType return null

i am using java se7 on mac, the oracle preview.
My problem is that "Files.probeContentType" returns null...is it possible that its due to the early status of se7 for mac?
My code:
if(directory == null) return;
String content = null;
try {
content = Files.probeContentType(directory.toPath());
} catch (IOException e) {
JOptionPane.showMessageDialog(main, e.toString());
return;
}
if(content == null)
{
return;
}
else if(content.contains("image"))
{
main.pctviewer.setImage(directory);
}
the name of the file is:
"/Users/admin/Desktop/temp/q12/formulare/Bildschirmfoto 2012-09-11 um 17.57.59.png"
and in debug mode in eclipse if i hover above File "file path = Unis-path(id:145)" is red
I have reported the bug to oracle again, hoping they will backport the jdk8 solution (I don't have much hope but you never know).
In the meantime you can use my own backport of the FileTypeDetector available at https://github.com/jeantil/jdk7-mimeutils the maven project packages to a jar which can be added to your classpath to enable mime type detection. I also provide a mime.types file to put in your home folder for the detection to work correctly. I extracted the mime.types file from some version of apache so it's pretty complete.
I found that the FileTypeDetector is buggy on OS X: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7133484
Apparently this will be fixed in Java 8.
Use the below approach to get mime type of file in Java 8 :
String location = "/Users/user/Desktop/leaf.jpg";
File file = new File(location);
Path source = Paths.get(location);
MimetypesFileTypeMap m = new MimetypesFileTypeMap(source.toString());
System.out.println( m.getContentType(file) );
Output of the above code is : 'image/jpg'

java code to search a file entire system, works fine on windows but infinite in linux ubuntu

Developing search utility to search a file entire computer system, works fine on windows platform but becomes an infinite process in ubuntu linux. Please help to overcome this flaw. The following is the main part of the code.
public static void fun(File f){ // root directory is passed as argument
try{
if(f.isDirectory()){
File [] fi=f.listFiles();
for(int i=0;i<fi.length;i++){
if(fileFound==true) break; // fileFound is boolean data type used as flag to indicate whether the file is found or not
System.out.println(fi[i].getName());
fun(fi[i]);
}
}
else{
if(f.getName().equalsIgnoreCase(txtFile.getText()) ||
(f.getName().toLowerCase().startsWith(txtFile.getText().toLowerCase())) ||
(f.getName().toLowerCase().endsWith(txtFile.getText().toLowerCase()))){
l.setText("file found " + f.getAbsolutePath()); // l is JLabel that indicated prints the info like file found and its path
fileFound=true;
}
}
}
catch(Exception e){
}
}
The error you are observing may be due to nested symbolic links.
The most effective approach to solve this problem would be to instead use FileUtils#iterateFiles from the excellent Apache Commons IO library.
There is something like "." (current directory) and ".." (above directory) in each dir in linux. Maybe thats your problem.
In unix like systems the first folder is "." (current folder)
and the second folder is ".." (the root folder)
you should skip the first 2 folders to avoid getting to the same folder over and over again.
try:
if(fi[i].getName() == "." || fi[i].getName() == "..")
continue;

How can I detect a Unix-like OS in Java?

Ok, I know that System.getProperty("os.name") will give me the name of the OS I'm running under, but that's not a lot of help. What I need to know is if the OS I'm running on is a 'Unix-like' OS, I don't care if it's HP-UX, AIX, Mac OS X or whatever.
From the list of possible os.name values it seems like a quick and dirty way of detecting a 'Unix-like' OS is checking if os.name does not contain "Windows". The false positives that will give me are OSes my code is very unlikely to encounter! Still, I'd love to know a better way if there is one.
Use the org.apache.commons.lang.SystemUtils utility class from Commons Lang, it has a nice IS_OS_UNIX constant. From the javadoc:
Is true if this is a POSIX compilant
system, as in any of AIX, HP-UX, Irix,
Linux, MacOSX, Solaris or SUN OS.
The field will return false if OS_NAME
is null.
And the test becomes:
if (SystemUtils.IS_OS_UNIX) {
...
}
Simple, effective, easy to read, no cryptic tricks.
I've used your scheme in production code on Windows XP, Vista, Win7, Mac OS 10.3 - 10.6 and a variety of Linux distros without an issue:
if (System.getProperty("os.name").startsWith("Windows")) {
// includes: Windows 2000, Windows 95, Windows 98, Windows NT, Windows Vista, Windows XP
} else {
// everything else
}
Essentially, detect Unix-like by not detecting Windows.
File.listRoots() will give you an array of the file system root directories.
If you are on a Unix-like system, then the array should contain a single entry "/" and on Windows systems you'll get something like ["C:", "D:", ...]
Edit: #chris_l: I totally forgot about mobile phones. Some digging turns up that Android returns a "/\0\0" - a slash followed by two null bytes (assumed to be a bug). Looks like we avoid false positives for the time being through luck and coincidence. Couldn't find good data on other phones, unfortunately.
It's probably not a good idea to run the same code on desktops and mobile phones regardless, but it is interesting to know. Looks like it comes down to needing to check for specific features instead of simply the system type.
Javadoc says: On UNIX systems the value of this
* field is '/'; on Microsoft Windows systems it is '\'.
System.out.println( File.separatorChar == '/' ? "Unix" : "Windows" );
System.getProperty("os.name"); is about the best you are going to get.
I agree with #Fuzzy in that I think the only way that Java intended you to be able to get that information was through the os.name property.
The only other things I can think of are:
Have a shell script or batch file wrapper to launch your Java app that passes in OS information using the -D argument to the JVM. Though given your description, this doesn't sound doable.
You could try to check for the existence of an OS-specific directory. For instance, you could assume the directory "/" will always exist on a Unix-like system, but not on Windows and do something like this:
if((new File("/")).exists())
{
System.out.println("I'm on a Unix system!");
}
Try to kick off a Unix-specific command line command like ls and check the return code. If it worked, you're on a Unix-like system, if not you're on Windows.
All of those solutions are really just hacks though and frankly I don't really feel all that great about any of them. You're unfortunately probably best off with your original thought. Fun, eh?
Use File.pathSeparator or File.separator. The first will return ";" in Windows and ":" in Unix. The second will return "\" in Windows and "/" in Unix.
You could try to execute the uname command - should be available on all unixoid systems.
package com.appspot.x19290;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class UnixCheck {
public static void main(String[] args) {
UnixCheck s = UnixCheck.S;
String isUnix = s.unix ? "is Unix" : "not Unix";
try {
System.out.println(isUnix + ", devnull: " + s.devnull.getPath());
} catch (NullPointerException e) {
System.out.println(isUnix + ", devnull: unknown");
}
}
public static final UnixCheck S = new UnixCheck();
public static final UnixCheck TEST = new UnixCheck(true);
public final boolean unix;
public final File devnull;
private UnixCheck() {
this(false);
}
private UnixCheck(boolean testing) {
String path;
path = testing ? "/<dev>/<no><such><null><device>" : "/dev/null";
File devnull = devnullOrNone(path);
if (devnull == null) {
this.unix = false;
path = testing ? "<no><such><null><device>" : "nul";
this.devnull = devnullOrNone(path);
} else {
this.unix = true;
this.devnull = devnull;
}
}
private static File devnullOrNone(String name) {
File file = new File(name);
if (file.isFile())
return null;
if (file.isDirectory())
return null;
try {
FileInputStream i = new FileInputStream(file);
try {
i.read();
} finally {
i.close();
}
} catch (IOException e) {
return null;
}
return file;
}
}

Categories