I want to get a file from the resource file, and to use it in string.
I tried this :
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("/resources/fileC.p12").getFile());
String data = String.valueOf(file);
but doesnt work, thanks for helping
I tried this but i had a error, it returns a null value
CodePudding user response:
new File
In java, File
means File. As in, an actual file on your actual harddisk. Resources aren't - they are entries in a jarfile and therefore not a file. Simply put, resources cannot be read this way.
Fortunately, File in general is barking up the wrong tree: The correct abstraction is InputStream
or similar - that represents 'any stream of bytes'. A file can be an InputStream. So can a network socket, a blob from a network, or, indeed, a resource being streamed to you by the classloader, which could very well be getting it from a network or generating it whole cloth - classloaders can do that. It's an abstract mechanism.
You're also doing it wrong - you want Type.class.getResource
. Your way is needlessly wordy and will fail in exotic scenarios (such as bootloaders and agents and the like, which have no classloader).
class Example {
public String getDataFromFileC() throws IOException {
try (var in = Example.class.getResourceAsStream("/resources/fileC.p12")) {
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}
}
}
This:
- Uses
getResourceAsStream
which gives you an inputstream. As I mentioned, if you mentionFile
, you lose. Hence, we don't. - Uses the proper form:
MyType.class.get
. This avoids issues when subclassing or in root classloader situations. MyType.class.get
needs a leading slash. thegetResource
on classloaders requires you not to have it (which explains why your snippet wouldn't work in any scenario - that leading slash).- Uses try-with-resources as you should.
- Propagates exceptions as you should.
- Configures charset which you should do anytime you go from bytes to strings or vice versa.
NB: Depending on your build system, it may package those resources in the jar as /fileC.p12
and not as /resources/fileC.p12
- in fact, that is likely. You may want to update this to "/fileC.p12"
.
NB2: String.valueOf(file);
does not read files. It just calls toString()
on the file object which gives you a path. Resources don't have to be a path so this cannot work. They do have a URL, which may or may not be useful. If you want that: return MyClass.class.getResource("/resources/fileC.p12").toString();
.
CodePudding user response:
String data = new String(getClass().getResourceAsStream("/fileC.p12").readAllBytes());
Your resource (which shouldn't be seen as a file as it could and probably should be packaged with your app) is at the root, so useful to start with '/' then it can be addressed from any package. Be cautious with Java >= 17 as that will be decoded by default as UTF-8, so if that's not the encoding, you will have to specify what is in the String
ctor. It might be safer to do that anyway.