My files hierarchy:
>resources:
>static:
>css:
>json:
>networks:
>network-list.json
>js:
>img:
I've tried to create a new file via:
File jsonNetworkDetailsFile = new File("/json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("static/json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("../json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("../../json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("/json/networks/network-list.json");
...and some more. None of it works.
I'm still getting the
java.io.FileNotFoundException: the system cannot find the path specified
What's the proper way?
EDIT
Found a solution. Had to include full path to the file like:
File jsonNetworkDetailsFile = new File("src/main/resources/static/json/networks/Turtlecoin/turtlecoin-pools.json");
EDIT2
As TwiN stated - it's impossible to reference a file through File object as soon as the app is packed into .jar. A proper solution would include:
InputStream jsonNetworkDetailsFile = new ClassPathResource("/static/json/networks/network-list.json").getInputStream();
InputStream is = new ClassPathResource("/someFile.txt").getInputStream();
where /someFile.txt is in your resources folder.
As mentioned in the documentation for ClassPathResource:
Supports resolution as java.io.File if the class path resource resides
in the file system, but not for resources in a JAR. Always supports
resolution as URL.
In other words, you'll want to use the getInputStream() method for your case:
InputStream is = new ClassPathResource("/someFile.txt").getInputStream();
try {
String contents = new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
System.out.println(contents); // do something with the content here
is.close();
} catch (IOException e) {
e.printStackTrace();
}
I'm mentioning this because ClassPathResource also has a getFile() method.
For more details, see reference
Try something like this :
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("classpath:static/json/networks/network-list.json").getFile());
You could also use :
#Value(value = "static/json/networks/network-list.json")
private Resource myFile;
And then :
myFile.getInputStream()
(will only work on a class annoted with #Component, #Service... etc)
you can try this to load files from ressources :
ClassLoader loader = Thread.currentThread().
getContextClassLoader();
InputStream configStream = loader.getResourceAsStream("/static/json/networks/network-list.json");
I think you should give the exact location to File object. Another solution:
File currDir = new File(".");
String path = currDir.getAbsolutePath();
// String path = "C:\\ExternalFiles\\"; // Or you can give staticly
File jsonNetworkDetailsFile = new File(path);
Hope it helps.
Related
I have been searching for 3 days now nonstop looking at every post I can find. My program runs on IntelliJ, but cannot run on an executable. Your help would be appreciated :)
More importantly, where can I find a in depth user-friendly tutorial? Is there a course or book I can pay for? On Udemy, the java classes completely fail to mention I/O such as classpath and URI. TutorialsPoint briefly goes over I/O buts its not indepth. Did I miss something? Is there an easier way to do all this??
Similar posts that have not worked for me:
Java Jar file: use resource errors: URI is not hierarchical
https://stackoverflow.com/a/27149287/155167
I am trying to load an excel file. I am using Maven. Apache POI says it needs a File. So InputStream does not work. http://poi.apache.org/components/spreadsheet/quick-guide.html#FileInputStream
When I java -jar jarFile, it gives me the error:
C:\Users\1010\Documents\Personal\MonsterManager>java -jar monsterManagerVer3.jar
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
at java.base/java.io.File.<init>(File.java:421)
at LoadExcel.<init>(LoadExcel.java:62)
at monsterRunner.<init>(monsterRunner.java:13)
at monsterRunner.main(monsterRunner.java:24)
Here is the code
public LoadExcel() throws IOException, URISyntaxException, InvalidFormatException {
mNames = null;
URL ins = this.getClass().getResource("/excel_List.xlsx");
if (ins == null)
throw new FileNotFoundException("The XLSX file didn't exist on the classpath");
ins.toString().replace(" ","%20"); //<-Runs without this part
File file = new File(ins.toURI()); //this is line 62
// File f = new File(getClass().getResource("/MyResource").toExternalForm());
//String path = this.getClass().getClassLoader().getResource("/excel_List.xlsx").toExternalForm();
//File file = new File(path);
OPCPackage pkg = OPCPackage.open(file);
XSSFWorkbook wb = new XSSFWorkbook(pkg);
//FileInputStream fis=new FileInputStream(new File(excelFile));
// XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet = wb.getSheetAt(0);
loadExcel(sheet);
cacheNames();
// fis.close();
wb.close();
}
If it helps here is the path to the excel file:
src\main\resources\excel_List.xlsx
UPDATE:
so I took the excel file out of the resources folder
\nameOfMyProgram\excel_List.xlsx
and now I get this error.
I tried several versions of using the classLoader, Class and Thread to solve this error from Different ways of loading a file as an InputStream
but I still cannot get it to compile.
Error and my code
If you have to use File object do not put xls-file into resources directory.
Maven puts all files from resources directory into jar.
Java can not create File object based on file in jar-file.
Put your xls-file somewhere in file system and create File object based on its URL.
Since your xls-file is not a resource do not use getResource.
Its URL is its full filename (with path).
This code below works with jar executable
String path = new File("excel_List.xlsx").getAbsoluteFile().toString();
File file = new File(path);
if(!file.exists()){
JOptionPane.showMessageDialog(null,"File not found!");
System.exit(0);
}
OPCPackage pkg = OPCPackage.open(file);
XSSFWorkbook wb = new XSSFWorkbook(pkg);
I am new to Spring Boot. I have this emailprop.properties in src/main/resource:
//your private key
mail.smtp.dkim.privatekey=classpath:/emailproperties/private.key.der
But I am getting the error as
classpath:\email properties\private.key.der (The filename, directory
name, or volume label syntax is incorrect)
How do I properly load this file?
Update-1
my java code is
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),
emailProps.getProperty("mail.smtp.dkim.privatekey"));
its working as "D:\\WorkShop\\MyDemoProj\\EmailService\\src\\main\\resources\\private.key.der"Instead of emailProps.getProperty("mail.smtp.dkim.privatekey")
Update-2
i have tried java code is
String data = "";
ClassPathResource cpr = new ClassPathResource("private.key.der");
try {
byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());
data = new String(bdata, StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),data);
Error is : java.io.FileNotFoundException: class path resource [classpath:private.key.der] cannot be resolved to URL because it does not exist
Tried Code is :
ClassPathResource resource = new ClassPathResource(emailProps.getProperty("mail.smtp.dkim.privatekey"));
File file = resource.getFile();
String absolutePath = file.getAbsolutePath();
Still same error..
please update the answer..
If you want to load this file runtime then you need to use ResourceLoader please have a look here for the documentation - section 8.4.
Resource resource = resourceLoader.getResource("classpath:/emailproperties/private.key.der");
Now if you want to keep this exact path in properties file you can keep it there and then load it in your Autowired constructor/field like that:
#Value("${mail.smtp.dkim.privatekey}") String pathToPrivateKey
and then pass this to the resource loader.
Full example you can find here. I don't want to copy paste it.
If your file is located here:
"D:\\WorkShop\\MyDemoProj\\EmailService\\src\\main\\resources\\private.key.der"
then it should be:
mail.smtp.dkim.privatekey=classpath:private.key.der
EDIT:
I see now, you are using DKIMSigner, which expects file-path string,
Try changing your code like this:
ClassPathResource resource = new ClassPathResource(emailProps.getProperty("mail.smtp.dkim.privatekey"));
File file = resource.getFile();
String absolutePath = file.getAbsolutePath();
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),absolutePath
);
My grade java project has the following structure.
As you can see the resources folder is in present in the class path.
But when I run the following in a class under java folder
new File("somefile.txt").exists()
I get FileNotFoundException.
Could anyone help me find why I am not able to access this file.
This is in the class path.
You can use.
ClassLoader classLoader = getClass().getClassLoader();
String filePath= classLoader.getResource("filename").getFile();
new File(filePath).exists();
For more info, you can go through this tutorial.
You can resolve your issue like below
Properties prop = new Properties();
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("somefile.txt");
if (inputStream != null) {
prop.load(inputStream);
} else {
throw new FileNotFoundException("Property file '" + fileName + "' not found in the classpath");
}
I found it from the post How to read properties file in Java
my spring boot project structure is like this
src
|-main
|--|-java
|--|-resources
static
|-css
|-images
|-js
now I want to write a file into the static/images folder
I tried to new File like
BufferedOutputStream stream =new BufferedOutputStream(new FileOutputStream(new File("static/images")));it will throw "No such file or directory" exception
but in other html file I can get the js by "js/jsFile.js"
new File("static/images") is right
I used new File("/static/images") so I got an Exception
I was in the situation where using Spring Boot I had to save the image into one directory which is accessed statically.
Below code worked perfect
byte[] imageByteArray ....
String fileName = "image.png";
String fileLocation = new File("static\\images").getAbsolutePath() + "\\" + fileName;
FileOutputStream fos = new FileOutputStream(fileLocation);
fos.write(imageByteArray);
fos.close();
Hope it helped.
#zhuochen shen is correct.
The thing is to happen me is Eclipse doesn't show write file. So I looked at file explore. File is writing correctly.
try {
Path path=Paths.get("static/images/"+productDto.getImage().getOriginalFilename());
Files.write(path,productDto.getImage().getBytes());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
enter image description here
enter image description here
I am new to OSGi and created an OSGi-bundle which I run in the Apache Felix OSGi-container.
There is a file resource contained in the bundle, which I need to pass to a method as a java.io.File. To instantiate a File-object, either an URI in the "file"-scheme or the path as string is necessary. How do I retrieve any of those in a clean way?
I tried using the
context.getBundle().getResource("/myfile") (where context is of type org.osgi.framework.BundleContext) which returns the URI bundle://6.0:0/myfile.
But this URI can't be converted to a File-instance using the File(URI uri) constructor since it has the "bundle"-scheme.
One could try to construct a path to the location knowing the working directory and exploiting the bundleId of my bundle, but I doubt this is the best practice.
Any ideas?
Since the file is inside your bundle, there is no way for you to get to it using a standard File. The URL you get from Bundle.getResource() is the correct way to get to these resources, since the OSGi APIs are intended to also work on systems without an actual file system. I would always try to stick to the OSGi API instead of using framework-specific solutions.
So, if you have control over the method, I would update it to take a URL, or maybe even an InputStream (since you probably just want to read from it). For convenience, you can always provide a helper method that does take a File.
If you don't have control over the method, you will have to write some helper method that takes the URL, streams it out to a file (for instance, File.createTempFile() will probably do the trick.
Maybe the API is confusable, but You can access a file inside an OSGI bundle like this:
URL url = context.getBundle().getResource("com/my/weager/impl/test.txt");
// The url maybe like this: bundle://2.0:2/com/my/weager/impl/test.txt
// But this url is not a real file path :(, you could't use it as a file.
// This url should be handled by the specific URLHandlersBundleStreamHandler,
// you can look up details in BundleRevisionImpl.createURL(int port, String path)
System.out.println(url.toString());
BufferedReader br =new BufferedReader(new InputStreamReader(url.openConnection().getInputStream()));
while(br.ready()){
System.out.println(br.readLine());
}
br.close();
getResource will find the resource through the whole OSGI container just like OSGI classloader theory.
getEntry will find the resource from local bundle. and the return url could be convert to file but inputStream.
Here is a question same with this: No access to Bundle Resource/File (OSGi)
Hope this helping you.
What I use is getClassLoader().getResourceAsStream():
InputStream inStream = new java.io.BufferedInputStream(this.getClass().getClassLoader().getResourceAsStream(fileName));
This way the file will be loaded from your resource dir. FileName should contain the path after "src/main/resources".
Full example here:
static public byte[] readFileAsBytes(Class c, String fileName) throws IOException {
InputStream inStream = new java.io.BufferedInputStream(c.getClassLoader().getResourceAsStream(fileName));
ByteArrayOutputStream out = new ByteArrayOutputStream();
int nbytes = 0;
byte[] buffer = new byte[100000];
try {
while ((nbytes = inStream.read(buffer)) != -1) {
out.write(buffer, 0, nbytes);
}
return out.toByteArray();
} finally {
if (inStream != null) {
inStream.close();
}
if (out != null) {
out.close();
}
}
}