This is my code:
public static void main(String[] args) {
try {
Scanner in = new Scanner(new File("f.txt"));
System.out.println("Next Double is: ");
System.out.println(in.nextDouble());
} catch (Exception e) {
e.printStackTrace();
}
}
And my "f.txt" is in my class path and I see it in my netbeans left column (that show the class path class files).
But this code throws file not found exception.
Why?
My "f.txt" file:
sdsdsdssf5s1d2s1 d5s s
s dlsfsf1s2 s1fsd1sd
sf31s3ds3ds
dgrh2t4jg6ng52.2 . 32 56. 2df5d5fd
sds2.3 2. 2 . 265.6 . 5 . 3 2 .f3sdsd
I'm not that familiar with netbeans but this looks promising: Netbeans - Reading a data file in src folder
In essence, put the entire path rather than the filename or move it to the build folder.
You could also consider using the class loader to read files as resources inside packages using getClass().getResourceAsStream("f.txt");. This is the preferred way of accessing resources since you no longer have to worry about absolute vs. relative paths. If a resource is in your classpath, you can access it.
it's recommend to use the ClassLoader as returned by Thread.currentThread().getContextClassLoader(), if the application uses multiple class loaders
This is a veeeeeeeeeeeery common problem in Java begginners.
First of all understand this theory:
If you have a package com.example, by common sense you would put the file in there NOO!
You must put the file in the root of all, (folder previous to com folder).
So you have to put f.txt in MyProject folder and everything will be okay.
About the mismatch exception, try to don't use such insecure methods as nextDouble(). What happens is that the reader is trying to cast the first 4 bytes as a double ("sd" string), and obviously that will throw an exception. Try to read line by line or character by character and do a simple char array from an array list.
Related
I'm trying to make a little program from school better, because I am more advanced then the others in my class and want to have a bit fun. It is a simple command line program in java but I want to make it with a full GUI.
So basically I want to access the JAR-File when executed and print the code written in a (by menu selected) class-file. I already know how to find the JAR-File and this works, but I can't find any way to get INTO the JAR-File. I tried creating a File object and putting the path to the JAR combined with the path to the class file I want to access. (Ex: "C:\temp\Test\program.jar\de\bbzsogr\Main.class" as found in WinRAR)
Here is some Code of the "CodeGrabber" class i wrote to access the JAR and then the file in the JAR.
public class CodeGrabber {
private static File JAR;
public static void grabCode(String className) {
try {
JAR = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
} catch (URISyntaxException e) {
e.printStackTrace();
}
System.out.println("JAR is located in: " + JAR);
// -> "JAR is located in: C:\temp\Test.jar"
System.out.println("Searching for \"" + JAR + File.separator + "ch" + File.separator + "bbzsogr" + File.separator + "Main.class");
// -> "Searching for "C:\temp\Test.jar\ch\bbzsogr\Main.class" "
File main = new File(JAR + File.separator + "ch" + File.separator + "bbzsogr" + File.separator + "Main.class");
try {
Scanner scanner = new Scanner(main);
while(scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
System.out.println("File MAIN not found...");
return;
}
// -> "File MAIN not found..."
}
}
I excepted to get a scrambled mess of data because the file, if I could access it, is still encoded/compiled, but I get the Message, that the wanted file was not found.
Thanks in advance!!
If you want to add and access a jar file inside a java program,you must import the java classes this jar contains and use their methods.You should write something like
import prog.mainclass
at the beginning of your program rather than trying to access it through the Jar.
For what you are asking now,the reason your program can't find the jar is because the path you imported is not valid.Java can't search inside any program but only inside a filesystem.Any path should be without dots like C:/temp/path and can't be,for example C:/temp.csv/path
TLDR: jar entries are not files.
A jar file is a file -- note 'a' meaning 'one'. A jar file is typically created by taking several files (often as many as hundreds, thousands, or more), usually at least some of them java (compiled) class files, (usually) compressing the data from each one, and writing the (compressed) data and name for each file as an entry in the jar. It is possible however for a jar entry not to come from a file; for example the manifest entry is often created 'on the fiy' rather than read from a file, and for a signed jar the signature entries always are. But even for jar entries that are created from files, the jar entries themselves are not files, and cannot be accessed as files using basic pre-NIO file access.
You have three options.
For a jar in the classpath -- which your jar obviously is, since you found it as the source for a loaded class, ClassLoader allows you to read any entry as a 'resource'. This is normally used for things like images, audio, video or other data packed in a jar with an application, but it works on entries that are class files.
// you can invoke it based on a known class like
InputStream is = Main.class.getResourceAsStream("path/for/package/Foo.class");
// or globally
InputStream is = ClassLoader.getResourceAsStream("path/for/package/Foo.class");
jar files are really zip files 'underneath', and Java has long allowed you to access zip files using java.io.ZipFile (directly) or java.io.ZipInputStream (layered on a FileInputStream). The former allows you to access entries 'randomly' using the so-called central directory, while the latter requires you to access entries in the order they occur in the file (and works on nonseekable underlying file forms like pipes and socket connections, but you don't need that here) which makes it a little less convenient for your purpose but still workable. See the javadoc for either.
NIO in Java 7 up (and pretty much everybody should be there by now) adds support for alternate filesystems which provide file-like (or at least stream-like) access to things other than actual files supported by the underlying operating system or its file system(s). And although more can be added, it comes with one alternate provider already installed which handles jars (really zips) -- just as you want.
String jarname = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
FileSystem fs = FileSystems.newFileSystem(Paths.get(jarname), null);
InputStream is = Files.newInputStream(fs.getPath("package/Foo.class"));
Note that in all cases I've opened an InputStream, not a Reader (or Scanner). Reader and Scanner are for text consisting of characters, and in most cases lines (which by definition contain characters). Class files have some characters here and there, but are mostly not characters and thus not text; they need to be read and processed as binary (with the few parts that are characters converted if desired). Have fun.
In Python the global variable __file__ is the full path of the current file.
System.getProperty("user.dir"); seems to return the path of the current working directory.
I want to get the path of the current .java, .class or package file.
Then use this to get the path to an image.
My project file structure in Netbeans looks like this:
(source: toile-libre.org)
Update to use code suggested from my chosen best answer:
// read image data from picture in package
try {
InputStream instream = TesseractTest.class
.getResourceAsStream("eurotext.tif");
bufferedImage = ImageIO.read(instream);
}
catch (IOException e) {
System.out.println(e.getMessage());
}
This code is used in the usage example from tess4j.
My full code of the usage example is here.
If you want to load an image file stored right next to your class file, use Class::getResourceAsStream(String name).
In your case, that would be:
try (InputStream instream = TesseractTest.class.getResourceAsStream("eurotext.tif")) {
// read stream here
}
This assumes that your build system copies the .tif file to your build folder, which is commonly done by IDEs, but requires extra setup in build tools like Ant and Gradle.
If you package your program to a .jar file, the code will still work, again assuming your build system package the .tif file next to the .class file.
Is there a way to get the file path of the .java file executed or compiled?
For completeness, the literal answer to your question is "not easily and not always".
There is a round-about way to find the source filename for a class on the callstack via StackFrameElement.getFileName(). However, the filename won't always be available1 and it won't necessarily be correct2.
Indeed, it is quite likely that the source tree won't be present on the system where you are executing the code. So if you needed an image file that was stashed in the source tree, you would be out of luck.
1 - It depends on the Java compiler and compilation options that you use. And potentially on other things.
2 - For example, the source tree can be moved or removed after compilation.
Andreas has described the correct way to solve your problem. Make sure that the image file is in your application's JAR file, and access it using getResource or getResourceAsStream. If your application is using an API that requires a filename / pathname in the file system, you may need to extract the resource from the JAR to a temporary file, or something like that.
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(getPackageParent(Main.class, false));
}
public static String getPackageParent(Class<?> cls, boolean include_last_dot)
throws Exception {
StringBuilder sb = new StringBuilder(cls.getPackage().getName());
if (sb.lastIndexOf(".") > 0)
if (include_last_dot)
return sb.delete(sb.lastIndexOf(".") + 1, sb.length())
.toString();
else
return sb.delete(sb.lastIndexOf("."), sb.length()).toString();
return sb.toString();
}
}
I use this method in opening files, but when i opened my project it won't run because its from a mac device. where do i store the txt file and what should i write instead of
(new File("D:\\description.txt"));
the method
Scanner inStream = null;
try {
inStream = new Scanner(new File("D:\\description.txt"));
}
catch (FileNotFoundException e) {
System.out.println("Erorr openenig the file");
}
while (inStream.hasNextLine ()) {
String line = inStream.nextLine();
System.out.println(line);
}
A couple of approaches you can use individually, or combine:
Hard-Coding elements that should be probably left configurable. Making the path configurable, means you can have something different depending on the platform you are on.
If the file is something that belongs with the distribution, make sure it is stored at the Class Path, and access it using YourClass.class.getResourceAsStream("/description.txt"); where YourClass is a class in your distribution. resource is a path relative to the location of the class (YourClass), so if you want it at the root of the Class Path, you will need to prefix with a forward slash "/". Here, you do not need to worry about OS conventions (forward vs backward slash). As remarked by someone else, you probably should not consider your file writable in that case.
Another typical approach, for storing things that are configuration, but specific to one user, is to store it at a default path location that get's automatically resolved. A good example is the Java System Property "user.home". In the case of a windows environment, it would resolve to the %HOME% environment variable (something like /User/myuserid).
I have been trying to read a file into Eclipse. I've looked over other questions, but those answers did not remedy the situation (refreshing the project folder, using getProperty and specifying the correct path, etc.) I've moved the file into every folder and I get the same error. I've copied the file into the directory as shown here:
I've also pasted the code below. It's stupidly simple. The error I get is "FileInputStream.open(String) line: not available [native method]".
Any help would be appreciated. Code is below.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Modulo {
public static void main(String[] args) throws FileNotFoundException {
File questions = new File("input.txt");
Scanner sc = new Scanner(questions);
while(sc.hasNext()){
int x = sc.nextInt();
String divide = sc.next();
int y = sc.nextInt();
System.out.println(x % y);
}
}
}
The answer depends.
If you want the file to be embedded within your application when your deploy it (as a Jar file for example), then you can't use File to reference it, as you've tried to include it within your application.
Eclipse further complicates the matter, as you can't included resources within your src directory, but needs to be maintained within a resources directory at the same level as your src folder (this folder may need to be included as part of your build process, but I only have a passing knowledge of how Eclipse works)...
Once you've corrected for all this, you will then need to use Class#getResource to load the resource...for example...
try (InputStream is = Modulo.class.getResourceAsStream("/input.txt")) {
Scanner sc = new Scanner(is);
//...
} catch (IOException exp) {
exp.printStackTrace();
}
However, if you want the file to be an external resource to your program, then you need to place it within a location relative to the location that the program is executed.
Normally, I would suggest the project directory, but I have a funny feeling that Eclipse run's it's Java programs in a different location ... and I don't know if you can change it...
In this case, you could use System.out.println(new File(".").getAbsolutePath()); or System.out.println(new File(".").getCanonicalPath()); or System.out.println(System.getProperty("user.dir")); which will tell you where you program is currently running and place the file there.
Of course, once build (into a Jar) you would need to place the file within a context that was relative to the location it was executed from...
You copy that file into Project folder parallel to src. This is the place base path of your code.
Eclipse by default looks for the file in the main project directory in your case Remainders, if your file is not there, you get an exception. Try placing the file directly under your project and run the same program, it should run correctly.
I am trying to understand the way Java resolves relative path in while creating a File object.
OS used: Windows
For the below snippet, I am getting an IOException as it cannot find the path:
#Test
public void testPathConversion() {
File f = new File("test/test.txt");
try {
f.createNewFile();
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
}
My understanding here is, Java treats the path provided as absolute and returns an error when the path does not exist. So it makes sense.
When I update the above code to use relative path:
#Test
public void testPathConversion() {
File f = new File("test/../test.txt");
try {
f.createNewFile();
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
}
It creates a new file and provides the below output:
test\..\test.txt
C:\JavaForTesters\test\..\test.txt
C:\JavaForTesters\test.txt
In this case, my assumption is, even though the path provided doesn't exist, because the path contains "/../", java treats this as a relative path and creates the file in the user.dir. So this also makes sense.
But if I update the relative path as below:
#Test
public void testPathConversion() {
File f = new File("test/../../test.txt");
try {
f.createNewFile();
System.out.println(f.getPath());
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
}
Then I get IOException: Access is denied.
My questions are:
why "test/../test.txt" is treated as a relative path and creates the file in "user.dir" but"test/../../test.txt" returns an error? Where does it attempt to create the file for the path "test/../../test.txt"?
When the specified relative path is not found, the file seems to be created in the user.dir. So, it appears to me that the below two scenarios does the same thing:
//scenario 1
File f = new File("test/../test.txt");
f.createNewFile();
//scenario 2
File f = new File("test.txt");
f.createNewFile();
So is there a real world case where one would use scenario 1 instead of scenario 2?
I suppose I am missing something obvious here or have fundamentally misunderstood relative paths. I went through the Java docs for File and I am not able to find an explanation for this. There are quite a few questions posted in Stack Overflow regarding relative paths, but the ones I looked up were for specific scenarios and not exactly about how relative paths are resolved.
It will be great if someone could please explain me how this works or point to some related links?
There is a concept of a working directory.
This directory is represented by a . (dot).
In relative paths, everything else is relative to it.
Simply put the . (the working directory) is where you run your program.
In some cases the working directory can be changed but in general this is
what the dot represents. I think this is C:\JavaForTesters\ in your case.
So test\..\test.txt means: the sub-directory test
in my working directory, then one level up, then the
file test.txt. This is basically the same as just test.txt.
For more details check here.
http://docs.oracle.com/javase/7/docs/api/java/io/File.html
http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html
When your path starts with a root dir i.e. C:\ in windows or / in Unix or in java resources path, it is considered to be an absolute path. Everything else is relative, so
new File("test.txt") is the same as new File("./test.txt")
new File("test/../test.txt") is the same as new File("./test/../test.txt")
The major difference between getAbsolutePath and getCanonicalPath is that the first one concatenates a parent and a child path, so it may contain dots: .. or .. getCanonicalPath will always return the same path for a particular file.
Note: File.equals uses an abstract form of a path (getAbsolutePath) to compare files, so this means that two File objects for the same might not be equal and Files are unsafe to use in collections like Map or Set.
The working directory is a common concept across virtually all operating systems and program languages etc. It's the directory in which your program is running. This is usually (but not always, there are ways to change it) the directory the application is in.
Relative paths are ones that start without a drive specifier. So in linux they don't start with a /, in windows they don't start with a C:\, etc. These always start from your working directory.
Absolute paths are the ones that start with a drive (or machine for network paths) specifier. They always go from the start of that drive.
Relative paths can be best understood if you know how Java runs the program.
There is a concept of working directory when running programs in Java. Assuming you have a class, say, FileHelper that does the IO under
/User/home/Desktop/projectRoot/src/topLevelPackage/.
Depending on the case where you invoke java to run the program, you will have different working directory. If you run your program from within and IDE, it will most probably be projectRoot.
In this case $ projectRoot/src : java topLevelPackage.FileHelper it will be src.
In this case $ projectRoot : java -cp src topLevelPackage.FileHelper it will be projectRoot.
In this case $ /User/home/Desktop : java -cp ./projectRoot/src topLevelPackage.FileHelper it will be Desktop.
(Assuming $ is your command prompt with standard Unix-like FileSystem. Similar correspondence/parallels with Windows system)
So, your relative path root (.) resolves to your working directory. Thus to be better sure of where to write files, it's said to consider below approach.
package topLevelPackage
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileHelper {
// Not full implementation, just barebone stub for path
public void createLocalFile() {
// Explicitly get hold of working directory
String workingDir = System.getProperty("user.dir");
Path filePath = Paths.get(workingDir+File.separator+"sampleFile.txt");
// In case we need specific path, traverse that path, rather using . or ..
Path pathToProjectRoot = Paths.get(System.getProperty("user.home"), "Desktop", "projectRoot");
System.out.println(filePath);
System.out.println(pathToProjectRoot);
}
}
Hope this helps.
On windows and Netbeans you can set the relative path as:
new FileReader("src\\PACKAGE_NAME\\FILENAME");
On Linux and Netbeans you can set the relative path as:
new FileReader("src/PACKAGE_NAME/FILENAME");
If you have your code inside Source Packages
I do not know if it is the same for eclipse or other IDE
Only slightly related to the question, but try to wrap your head around this one. So un-intuitive:
import java.nio.file.*;
class Main {
public static void main(String[] args) {
Path p1 = Paths.get("/personal/./photos/./readme.txt");
Path p2 = Paths.get("/personal/index.html");
Path p3 = p1.relativize(p2);
System.out.println(p3); //prints ../../../../index.html !!
}
}
I went off of peter.petrov's answer but let me explain where you make the file edits to change it to a relative path.
Simply edit "AXLAPIService.java" and change
url = new URL("file:C:users..../schema/current/AXLAPI.wsdl");
to
url = new URL("file:./schema/current/AXLAPI.wsdl");
or where ever you want to store it.
You can still work on packaging the wsdl file into the meta-inf folder in the jar but this was the simplest way to get it working for me.