Strange getName() result on File in linux - java

I have some code that reads the name from an UNC path:
File f = new File(//fileshare/folder/file.txt)
System.out.println(f.getName())
On windows this gives:
file.txt
but on linux it gives:
//fileshare/folder/file.txt
why?

On my system (Ubuntu 12.04) it gives file.txt:
$ cat Test.java
import java.io.File;
class Test {
public static void main(String[] args) {
File f = new File("//fileshare/folder/file.txt");
System.out.println(f.getName());
}
}
$ javac Test.java && java Test
file.txt
f.getPath() returns /fileshare/folder/file.txt, which shows that multiple slashes get reduced to one, as is customary (required?) on Unix systems.
Of course, a UNC path is meaningless on anything but Windows.

Try using org.apache.commons.io.FilenameUtils from Apache Commons, the method getName() should ensure consistent parsing of the full path regardless of the platform where you are running.

Related

Why is Jenkins having problems with UTF 8

I have a Jenkins job running. I just want to get all files. In every file name there is a Chinese letter. So the problem is now that Jenkins has problems reading in those files. Jenkins makes just "?" out of the Asian letter. The second problem is. Actually it is more than 100 files. But Jenkins only gives me 20 files. Maybe now a lot of files will look the same because of the question mark "?" .
Does anyone know how I can fix this. The problem only occurs on Jenkins ( running on Linux ) . On my local machine in Eclipse it works though.
File resourcePath = new File("resources/china_data/");
File[] files = resourcePath.listFiles();
for (final File file : files)
{
System.out.console(file.getName);
}
An alternative solution is to use the new java.nio.Path api in place of the java.io.File api
Also try setting the below in your code initially.
System.setProperty("sun.jnu.encoding","utf-8");
System.setProperty("file.encoding","UTF-8");
Assuming you are using System.out.println, this happens when the program runs with an ASCII locale:
$ cat Main.java
import java.util.*;
import java.io.*;
class Main {
public static void main(String[] args) throws Exception {
File resourcePath = new File("resources/china_data/");
File[] files = resourcePath.listFiles();
for (final File file : files)
{
System.out.println(file.getName());
}
}
}
$ javac Main.java
$ LC_CTYPE=C java Main
???????
When the program runs with a UTF-8 capable locale, either from the environment or configured through Java, you get the expected result:
$ LC_CTYPE=en_US.UTF-8 java Main
中华人民共和国
$ LC_CTYPE=C java -Dfile.encoding=UTF-8 Main
中华人民共和国
If you're not sure how to configure your server, you can also do this from within Java:
System.setOut(new PrintStream(System.out, true, "UTF-8"));

Uniquely identify file in Java

Im on Linux and my Java application is not intended to be portable.
I'm looking for a way to identify a file uniquely in Java. I can make use of statfs syscall since the pair (f_fsid, ino) uniquely identifies a file (not only across a file system) as specified here: http://man7.org/linux/man-pages/man2/statfs.2.html
The question is if it is possible extract fsid from Java directly so I can avoid writing JNI function?
inode can be extracted with NIO, but how about fsid? inode and fsid comes from different structure and are operated by different syscalls...
This java example demonstrates how to get the unix inode number of a file.
import java.nio.file.*;
import java.nio.file.attribute.*;
public class MyFile {
public static void main(String[] args) throws Exception {
BasicFileAttributes attr = null;
Path path = Paths.get("MyFile.java");
attr = Files.readAttributes(path, BasicFileAttributes.class);
Object fileKey = attr.fileKey();
String s = fileKey.toString();
String inode = s.substring(s.indexOf("ino=") + 4, s.indexOf(")"));
System.out.println("Inode: " + inode);
}
}
The output
$ java MyFile
Inode: 664938
$ ls -i MyFile.java
664938 MyFile.java
credit where credit is due: https://www.javacodex.com/More-Examples/1/8
I would suggest the GIT method of hashing the file contents. This is proof against copying and renaming.
Java is supposed to be platform independent so using Unix specific methods may not be what you want.

Inputting file name through main function argument (args[0])

EDIT: to run my code i am using "java filename.java input1.txt" is this correct?
I am creating a program where i have to tokenize a string into separate words and that string is in a text file. I have to specify the text file name in the terminal through command line arguments (args[0], etc). I am able to scan and print the content of the text file if i specify through paths but when i try to do it using args[0] it doesn't seem to work. I am using net beans. I will attach my section of code here:
public static void main(String[] args) {
try {
File f = new File(args[0]);
//using this commented out section using paths works File f = new
//File("NetBeansProjects/SentenceUtils/src/input1.txt");
Scanner input = new Scanner(new FileInputStream(f));
while(input.hasNext()) {
String s = input.next();
System.out.println(s);
}
} catch(FileNotFoundException fnfe) {
System.out.println("File not found");
}
SentenceUtils s = new SentenceUtils();
}
java filename.java input1.txt
is not correct for running a java program, you need to compile the *.java file to get a *.class file which you can then run like:
java filename input1.txt
assuming your class is in the default package and you are running the command in the output directory of your compile command, or using the fully qualified class name of the class, i.e. including the package name. For example if your class is in the package foo/bar/baz (sub folders in your source folder) and has the package declaration package foo.bar.baz;, then you need to specify your class like this:
java [-cp your-classpath] foo.bar.baz.filename input1.txt
for input1.txt to be found it has to be in the same directory where you run the command.
your-classpath is a list of directories separated by a system dependent delimiter (; for windows, : for linux, ...) or archives which the java command uses to look up the class to run specified and its dependencies.
NetBeansProjects/SentenceUtils/src/input1.txt is a relative path.
File f = new File("NetBeansProjects/SentenceUtils/src/input1.txt");
if this works then it means that the current working directory (i.e. the directory from which all relative paths are calculated) is the the rectory named NetBeansProjects.
You get FileNotFoundException because your file is expected to be in
NetBeansProjects/input1.txt
To find out which is the current working directory for your running program you can add the following statement:
System.out.println(new File("").getAbsolutePath());
Place input.txt in that directory and it will be found.
Alternatively you can pass the absolute path of your input file. an absolute path is a path that can be used to locate your file from whatever location your program is running from on your local filesystem. For example:
java -cp <your-classpath> <fully-qualified-name-of-class> /home/john/myfiles/myprogects/...../input1.txt
To sum up, what you need to know/do is the following:
the location of your program class and its package (filename)
the location of your input file (input.txt)
pass the correct argument accordingly

Setx Called From Java Not Working Correctly

I'm using the setx command to modify the PATH system environment variable. Here is the command I'm using:
setx PATH "%PATH%;C:\Python34" /M
When this is ran as batch file and as administrator, it works properly and adds the new entry to the PATH.
However if I'm trying to run this from within my Java application it starts to behave weirdly.
First of all, the Java code used to execute the batch file:
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
public class BatchFile
{
public static void execute(String batchFilePath) throws IOException,
InterruptedException
{
Process process = Runtime.getRuntime().exec("cmd /c " + batchFilePath);
process.waitFor();
printResults(process);
}
private static void printResults(Process process) throws IOException
{
String standardOutput = getString(process.getInputStream());
String standardError = getString(process.getErrorStream());
if (!standardOutput.equals(""))
{
System.out.println(standardOutput);
}
if (!standardError.equals(""))
{
System.out.println(standardError);
}
}
private static String getString(InputStream inputStream) throws IOException
{
return IOUtils.toString(inputStream).trim();
}
}
Invoked like this:
BatchFile.execute("MyBat.bat");
Before running, my PATH looks like this:
c:\devkitPro\msys\bin;C:\devkitPro\devkitPPC\bin;C:\devkitPro\devkitPPC\powerpc-eabi\bin;C:\Program Files\Java\jdk1.8.0_45\bin;C:\ProgramData\Oracle\Java\javapath;C:\Python27\Lib\site-packages\PyQt4;C:\devkitPro\devkitARM\bin;C:\Python27\Lib\site-packages\PyQt4;C:\Program Files (x86)\Wiimm\WIT;C:\Windows\System32;C:\MinGW\bin;C:\MinGW\libexec\gcc\mingw32\4.8.1;C:\Python34;C:\MinGW\msys\1.0\bin;C:\Program Files (x86)\Git\cmd;C:\Windows\SysWOW64;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Skype\Phone\
After running the Java code however, it turns into this:
C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;c:\devkitPro\msys\bin;C:\devkitPro\devkitPPC\bin;C:\devkitPro\devkitPPC\powerpc-eabi\bin;C:\Program Files\Java\jdk1.8.0_45\bin;C:\ProgramData\Oracle\Java\javapath;C:\Python27\Lib\site-packages\PyQt4;C:\devkitPro\devkitARM\bin;C:\Python27\Lib\site-packages\PyQt4;C:\Program Files (x86)\Wiimm\WIT;C:\Windows\System32;C:\MinGW\bin;C:\MinGW\libexec\gcc\mingw32\4.8.1;C:\Python34;C:\MinGW\msys\1.0\bin;C:\Program Files (x86)\Git\cmd;C:\Windows\SysWOW64;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin\;C:\Program Files
The message being printed out on the console is as follows:
D:\Programs\Portable\Eclipse\workspace\My Application>setx PATH "C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin/server;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/bin;C:/Program Files/Java/jdk1.8.0_45/bin/../jre/lib/amd64;c:\devkitPro\msys\bin;C:\devkitPro\devkitPPC\bin;C:\devkitPro\devkitPPC\powerpc-eabi\bin;C:\Program Files\Java\jdk1.8.0_45\bin;C:\ProgramData\Oracle\Java\javapath;C:\Python27\Lib\site-packages\PyQt4;C:\devkitPro\devkitARM\bin;C:\Python27\Lib\site-packages\PyQt4;C:\Program Files (x86)\Wiimm\WIT;C:\Windows\System32;C:\MinGW\bin;C:\MinGW\libexec\gcc\mingw32\4.8.1;C:\Python34;C:\MinGW\msys\1.0\bin;C:\Program Files (x86)\Git\cmd;C:\Windows\SysWOW64;C:\Program Files\TortoiseSVN\bin;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Skype\Phone\;D:\Programs\Portable\Eclipse;;C:\Python34" /M
SUCCESS: Specified value was saved.
WARNING: The data being saved is truncated to 1024 characters.
As you can see, a lot of rubbish Java directories have been added to the PATH contents at the beginning and it exceed the maximum limit of 1024 characters so it cuts off at the end. At the end there is an unwanted Eclipse directory added and there also are two semicolons before the actual Python path.
How do I get rid of the unwanted behavior when invoking the batch file using Java? I want the correct default behavior like when the setx command is invoked normally on cmd.
A while ago I was stuck at the same problem.
The simple answer is:
Do not use eclipse to start your program.
Eclipse will change your environment variables quite a lot for the execution. (including PATH)
You might have guessed it now but eclipse closes the PATH with a ; so when you call
setx PATH "%PATH%;C:\Python34" /M
you add another ; in front of the python path.
Just check by changing your batch to
echo %PATH%
Then run from eclipse and make another testrun from the command line (java -cp . MyMainClass) to see the difference.
Regarding the "WARNING: The data being saved is truncated to 1024 characters." limitation of setx you might want to have a look there: https://superuser.com/questions/387619/overcoming-the-1024-character-limit-with-setx

execute jar file in java program

I want to create an java program to compress an css file using YUI
I am new learner in java.
My Code is:
import java.io.BufferedInputStream;
import java.io.IOException;
public class Run extends Object
{
public static void main(String args[]) throws IOException, InterruptedException
{
System.out.println("Calling jar");
Process p = Runtime.getRuntime().exec("java -Xmx32m -jar yui.jar in.css");
BufferedInputStream bis = new BufferedInputStream(p.getInputStream());
synchronized(p)
{
p.waitFor();
}
System.out.println(p.exitValue());
int b = 0;
while((b = bis.read()) > 0)
{
System.out.print((char)b);
}
System.out.println("Called jar");
}
}
I took reference from here.
the command:
java -Xmx32m -jar yui.jar in.css
works fine in cmd but I get no output when I run above program
the output I get for above is:
Calling jar
1
Called jar
Please tell Me what I am doing wrong or what is the right way of doing this.
You are getting the "1" because there is nothing to read in the stream.
I'm guessing that you're trying to run the file from Eclipse or some other IDE. If so, you need to place your yui.jar and in.css files to same directory relative to where your Run class is.
If you're using default run configurations, you'll just want to put the files into the root directory of your eclipse project. For example, this works for me:
Test
src
com
test
Run.java
yui.jar
in.css
A better way to handle your situation is to use absolute or relative paths instead of just specifiying yui.jar or in.css. Create two variables for the two relative paths and then create the command string.

Categories

Resources