MediaPlayer.setDataSource(String) not working with local files - java

I am able to play a local mp3 if I use the static method MediaPlayer.create(context, id) but it's not working if I use the non-static method MediaPlayer.setDataSource(String). What's happening is that I am getting a synchronous exception when I call MediaPlayer.prepare():
prepare exceptionjava.io.IOException: Prepare failed.: status=0x1
Here is my code (omitted logging):
String filename = "android.resource://" + this.getPackageName() + "/raw/test0";
mp = new MediaPlayer();
try { mp.setDataSource(filename); } catch (Exception e) {}
try { mp.prepare(); } catch (Exception e) {}
mp.start();
Note that I am not getting an errors about file not found or anything. The full name of the file is test0.mp3 and I place it in the /res/raw/ directory in Eclipse.
I assume that I am setting the path incorrectly but all the examples I find online use the FileDescriptor version of setDataPath instead of the String version of setDataPath.
EDIT: I am also able to play a local mp3 if I use the method MediaPlayer.setDataSource(FileDescriptor) and place the files in the /assets/ directory in Eclipse.
EDIT #2: I accepted the answer that this is not possible, but then realized that the library I am using (openFrameworks) actually does use the String method to load a file. See here:
https://github.com/openframeworks/openFrameworks/blob/master/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidSoundPlayer.java

Alternative Solution #1: Using Resources.getIdentifier()
Why not use getResources().getIdentifier() to get id of the resource and use the static MediaPlayer.create() as usual?
public int getIdentifier (String name, String defType, String defPackage)
getIdentifier() takes your resource name (test0), resource type(raw), your package name and returns the actual resource id.
MediaPlayer mp;
//String filename = "android.resource://" + this.getPackageName() + "/raw/test0";
mp=MediaPlayer.create(getApplicationContext(), getResources().getIdentifier("test0","raw",getPackageName()));
mp.start();
I've tested this code and it works.
Update #1:
Alternative Solution #2: Using Uri.parse()
I've tested this code as well and it works too. Pass your resource path as URI to setDataSource(). I just made that change to your code to get it work.
String filename = "android.resource://" + this.getPackageName() + "/raw/test0";
mp = new MediaPlayer();
try { mp.setDataSource(this,Uri.parse(filename)); } catch (Exception e) {}
try { mp.prepare(); } catch (Exception e) {}
mp.start();
Update #2: Answer is NO
About setDataSource(String) call
After seeing your comment, it looks like you exactly want setDataSource(string) to be used for your purpose. I don't understand why. But, what I assume is, for some reason you are trying to avoid using "context". If that is not the case then the above two solutions should work perfectly for you or if you are trying to avoid context, I'm afraid that is not possible with the function with signature setDataSource(String) call. The reason is as below,
MediaPlayer setDataSource() function has these below options out of which you are only interested in setDataSource(String),
setDataSource(String) internally calls setDataSource(String path, String[] keys, String[] values) function. If you can check its source,
public void setDataSource(String path)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
setDataSource(path, null, null);
}
and if you check setDataSource(String path, String[] keys, String[] values) code, you will see the below condition filtering the path based on its scheme, particularly if it is "file" scheme it calls setDataSource(FileDescriptor) or if scheme is non "file", it calls native JNI media function.
{
final Uri uri = Uri.parse(path);
final String scheme = uri.getScheme();
if ("file".equals(scheme)) {
path = uri.getPath();
} else if (scheme != null) {
// handle non-file sources
nativeSetDataSource(
MediaHTTPService.createHttpServiceBinderIfNecessary(path),
path,
keys,
values);
return;
}
final File file = new File(path);
if (file.exists()) {
FileInputStream is = new FileInputStream(file);
FileDescriptor fd = is.getFD();
setDataSource(fd);
is.close();
} else {
throw new IOException("setDataSource failed.");
}
}
In the above code, your resource file URI scheme will not be null (android.resource://) and setDataSource(String) will try to use native JNI function nativeSetDataSource() thinking that your path is http/https/rtsp and obviously that call will fail as well without throwing any exception. Thats why your call to setDataSource(String) escapes without an exception and gets to prepare() call with the following exception.
Prepare failed.: status=0x1
So setDataSource(String) override cannot handle your resource file. You need to choose another override for that.
On the other side, check setDataSource(Context context, Uri uri, Map headers) which is used by setDataSource(Context context, Uri uri), it uses AssetFileDescriptor, ContentResolver from your context and openAssetFileDescriptor to open the URI which gets success as openAssetFileDescriptor() can open your resource file and finally the resultant fd is used to call setDataSource(FileDescriptor) override.
AssetFileDescriptor fd = null;
try {
ContentResolver resolver = context.getContentResolver();
fd = resolver.openAssetFileDescriptor(uri, "r");
// :
// :
// :
if (fd.getDeclaredLength() < 0) {
setDataSource(fd.getFileDescriptor());
} else {
setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getDeclaredLength());
}
To conclude, you cannot use setDataSource(String) override as is to use your resource mp3 file. Instead, if you want use string to play your resource file you can use either MediaPlayer.create() static function with getIdentifier() as given above or setDataSource(context,uri) as given in Update#1.
Refer to the complete source code for more understanding here: Android MediaPlayer
Update #3:
openFrameworks setDataSource(String):
As I have mentioned in the comments below, openFrameworks uses android MediaPlayer code asis. If you can refer to Line no: 4,
import android.media.MediaPlayer;
and Line no: 26, 27, 28 and 218
player = new MediaPlayer(); //26
player.setDataSource(fileName); //27
player.prepare(); //28
private MediaPlayer player; //218
So, if you try to pass ardroid.resource//+ this.getPackageName() + "raw/test0" to setDataSource() using openFrameworks, you will still get the same exception as I explained in Update#2. Having said that, I just tried my luck searching Google to double sure what I am saying and found this openFrameworks forum link where one of the openFrameworks core developer arturo says,
don't know exactly how the mediaPlayer works but everything in res/raw
or bin/data gets copied to /sdcard/cc.openframeworks.packagename
Based on that comment, you may try using the copied path in setDataSource(). Using resource file on setDataSource(String) of MediaPlayer is not possible as it cannot accept resource file path. Please note that, I said "resource file path" starts with the scheme android.resource// which is actually a jar location (within your apk), not a physical location. Local file will work with setDataSource(String) which starts with the scheme file://.
To make you clearly understand what you are trying to do with a resource file, try executing this below code and see the result in logcat,
try{
Log.d("RESURI", this.getClass().getClassLoader().getResource("res/raw/test0").toURI().toString());
}
catch(Exception e) {
}
You'll get the result as,
jar:file:/data/app/<packagename>/<apkname>.apk!/res/raw/test0
that is to show you that the resource file you are trying to access is not actually a file in physical path but a jar location (within apk) which you cannot access using setDataSource(String) method. (Try using 7zip to extract your apk file and you will see the res/raw/test0 in it).
Hope that helps.
PS: I know its bit lengthy answer, but I hope this explains it in detail. Leaving the alternative solutions in the top if that can help others.

Like the android documentation said
Arbitrary files to save in their raw form. To open these resources
with a raw InputStream, call Resources.openRawResource() with the
resource ID, which is R.raw.filename.
However, if you need access to original file names and file hierarchy,
you might consider saving some resources in the assets/ directory
(instead of res/raw/). Files in assets/ are not given a resource ID,
so you can read them only using AssetManager.
So you need to use a InputStream to read the audio file before set it to the media player.
I suggest you to put the audio file in the assets folder like you said you played
:)

Below code working for me i think this code will help you
player = MediaPlayer.create(this,R.raw.test0);
player.setLooping(true); // Set looping
player.setVolume(100,100);
player.start();
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
player.stop();
player.release();
}

When dealing with a raw resource, you should rely on the following constructor:
public static MediaPlayer create (Context context, int resid)
Convenience method to create a MediaPlayer for a given resource id. On success, prepare() will already have been called and must not be called again.
The code looks like
mediaPlayer = MediaPlayer.create(this, R.raw.test0);
mediaPlayer.start();
Don't forget to call mediaPlayer.release() when you're done with it.
(source)

From here,
When path refers to a local file, the file may actually be opened by a process other than the calling application. This implies that the pathname should be an absolute path (as any other process runs with unspecified current working directory), and that the pathname should reference a world-readable file. As an alternative, the application could first open the file for reading, and then use the file descriptor form setDataSource(FileDescriptor).
Try,
String filePath = "path/file.mp3";
File file = new File(filePath);
FileInputStream inputStream = new FileInputStream(file);
mediaPlayer.setDataSource(inputStream.getFD());
inputStream.close();
Hope it Helps!

You have to use setDataSource(#NonNull Context context, #NonNull Uri uri) instead of setDataSource(String path)
Since you want to resolve resource internal application resources, you have to provide Context which would be used to resolve this stuff
Also if you will take a look inside these two methods you will notice they use different strategies to find resulting resource.

Try this:
if(mediaPlayer != null ){
if (mediaPlayer.isPlaying()){mediaPlayer.stop();}
mediaPlayer.reset(); //this line is important!
String path = File.separator + "sdcard" + File.separator + utilsFields.repoDirRoot + File.separator + media.mp4;
try {
mediaPlayer.setDataSource(path);
}catch (Exception ignored){}
try {
mediaPlayer.prepare();
}catch (Exception ignored){}
mediaPlayer.start();
}

Related

Android - Copy image to clipboard, anyone got this working?

I am trying to copy a image file from my apk to the clipboard.
Here is how I am approaching it (roughly, i'm using a content provider locally which is out of the scope of the question.
ClipboardManager mClipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ContentValues values = new ContentValues(2);
values.put(MediaStore.Images.Media.MIME_TYPE, "Image/jpg");
values.put(MediaStore.Images.Media.DATA, filename.getAbsolutePath());
ContentResolver theContent = getContentResolver();
Uri imageUri = theContent.insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
ClipData theClip = ClipData.newUri(getContentResolver(), "Image", imageUri);
mClipboard.setPrimaryClip(theClip);
With this code two things can happen:
1) java.lang.IllegalStateException: Unable to create new file
2) When pasting it only pastes the URI itself, not the image (even in compatible apps)
I don't see any example of anyone getting image pasting on android working, and I have searched for an answer extensively, both on google and stack overflow.
Can anyone help with this?
I would really appreciate someones assistance here.
PS: If it's just not possible to do I would also like to know that, to save wasting anymore time on this.
Thanks!
I have an option. Use the app SwiftKey as your keyboard on Android (it worked on Android 10). It allow you to access your photos library, so you will need to 1) download the image 2) open whatever app you are using and want to paste the image 3) using your SwiftKey keyboard, click on the "+" signal and then on the "pin" symbol (should be in the first line). 4) Finally, click on "create new" and it will access your photos to insert IN-LINE ANYWHERE.
I know that's not the best solution while on iOS you can just tap copy and paste. But it was the only solution that worked for me. Try for yourself. I hope that helps :)
There is no indication that such functionality is supported in Android.
The behavior is correct and the uri is the copied data not the bitmap.
It depends on whether the place you are pasting in can handle this uri.
The issue to the OP is this
values.put(MediaStore.Images.Media.MIME_TYPE, "Image/jpg");
This is an invalid mime type. It should be
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
you can not copy that to clipboard because its impossible;
but you can do that by copying that to sdcard and then access that from every where that you want;
here is some code that helped me a lot and can help you too:
Context Context = getApplicationContext();
String DestinationFile = "the place that you want copy image there like sdcard/...";
if (!new File(DestinationFile).exists()) {
try {
CopyFromAssetsToStorage(Context, "the pictures name in assets folder of your project", DestinationFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void CopyFromAssetsToStorage(Context Context, String SourceFile, String DestinationFile) throws IOException {
InputStream IS = Context.getAssets().open(SourceFile);
OutputStream OS = new FileOutputStream(DestinationFile);
CopyStream(IS, OS);
OS.flush();
OS.close();
IS.close();
}
private void CopyStream(InputStream Input, OutputStream Output) throws IOException {
byte[] buffer = new byte[5120];
int length = Input.read(buffer);
while (length > 0) {
Output.write(buffer, 0, length);
length = Input.read(buffer);
}
}

How do I get a Java resource as a File?

I have to read a file containing a list of strings. I'm trying to follow the advice in this post. Both solutions require using FileUtils.readLines, but use a String, not a File as the parameter.
Set<String> lines = new HashSet<String>(FileUtils.readLines("foo.txt"));
I need a File.
This post would be my question, except the OP was dissuaded from using files entirely. I need a file if I want to use the Apache method, which is the my preferred solution to my initial problem.
My file is small (a hundred lines or so) and a singleton per program instance, so I do not need to worry about having another copy of the file in memory. Therefore I could use more basic methods to read the file, but so far it looks like FileUtils.readLines could be much cleaner. How do I go from resource to file.
Apache Commons-IO has an IOUtils class as well as a FileUtils, which includes a readLines method similar to the one in FileUtils.
So you can use getResourceAsStream or getSystemResourceAsStream and pass the result of that to IOUtils.readLines to get a List<String> of the contents of your file:
List<String> myLines = IOUtils.readLines(ClassLoader.getSystemResourceAsStream("my_data_file.txt"));
I am assuming the file you want to read is a true resource on your classpath, and not simply some arbitrary file you could just access via new File("path_to_file");.
Try the following using ClassLoader, where resource is a String representation of the path to your resource file in your class path.
Valid String values for resource can include:
"foo.txt"
"com/company/bar.txt"
"com\\company\\bar.txt"
"\\com\\company\\bar.txt"
and path is not limited to com.company
Relevant code to get a File not in a JAR:
File file = null;
try {
URL url = null;
ClassLoader classLoader = {YourClass}.class.getClassLoader();
if (classLoader != null) {
url = classLoader.getResource(resource);
}
if (url == null) {
url = ClassLoader.getSystemResource(resource);
}
if (url != null) {
try {
file = new File(url.toURI());
} catch (URISyntaxException e) {
file = new File(url.getPath());
}
}
} catch (Exception ex) { /* handle it */ }
// file may be null
Alternately, if your resource is in a JAR, you will have to use Class.getResourceAsStream(resource); and cycle through the file using a BufferedReader to simulate the call to readLines().
using a resource to read the file to a string:
String contents =
FileUtils.readFileToString(
new File(this.getClass().getResource("/myfile.log").toURI()));
using inputstream:
List<String> listContents =
IOUtils.readLines(
this.getClass().getResourceAsStream("/myfile.log"));

How to check whether a known uri file exists in Android storage?

The file uri is known, such as
`file:///mnt/sdcard/Download/AppSearch_2213333_60.apk`
I want to check if this file can open or not in background, how to do?
Check if a file of a path exists like this:
File file = new File("/mnt/sdcard/Download/AppSearch_2213333_60.apk" );
if (file.exists()) {
//Do something
}
Keep in mind to remove something like "file://" etc. otherwise use:
File file = new File(URI.create("file:///mnt/sdcard/Download/AppSearch_2213333_60.apk").getPath());
if (file.exists()) {
//Do something
}
Also you have to set proper permissions for your app in the AndroidManifest.xml to access the sdcard:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I might be a little late to the party here, but I was looking for a solution to a similar problem and was finally able to find a solution for all possible edge cases. The solution is a follows:
boolean bool = false;
if(null != uri) {
try {
InputStream inputStream = context.getContentResolver().openInputStream(uri);
inputStream.close();
bool = true;
} catch (Exception e) {
Log.w(MY_TAG, "File corresponding to the uri does not exist " + uri.toString());
}
}
If the file corresponding to the URI exists, then you will have an input stream object to work with, else an exception will be thrown.
Do not forget to close the input stream if the file does exist.
NOTE:
DocumentFile sourceFile = DocumentFile.fromSingleUri(context, uri);
boolean bool = sourceFile.exists();
does handle most edge cases, but what I found out was that if a file is created programmatically and stored in some folder, the user then visits the folder and manually deletes the file (while the app is running), DocumentFile.fromSingleUri wrongly says that the file exists.
DocumentFile sourceFile = DocumentFile.fromSingleUri(context, uri);
boolean bool = sourceFile.exists();
Start by extracting the filename using URI:
final String path = URI.create("file:///mnt/sdcard/Download/AppSearch_2213333_60.apk")
.getPath(); // returns the path segment of this URI, ie the file path
final File file = new File(path).getCanonicalFile();
// check if file.exists(); try and check if .canRead(), etc
It is advisable to use URI here, since it will take care of decoding all possible spaces/characters illegal in URIs, but legal in file names.
Above answers will not work for all versions of Android (see Get filename and path from URI from mediastore and Get real path from URI, Android KitKat new storage access framework), but there is an easy way using DocumentsContract:
DocumentsContract.isDocumentUri(context,myUri)
I wrote a function that checks if a file exists on a given path. The path might me absolute path or Uri path.
fun localFileExist(localPathOrUri: String?, context:Context): Boolean {
if (localPathOrUri.isNullOrEmpty()) {
return false
}
var exists = File(localPathOrUri).exists()
if (exists) {
return exists
}
val cR = context.getContentResolver()
val uri = Uri.parse(localPathOrUri)
try {
val inputStream = cR.openInputStream(uri)
if (inputStream != null) {
inputStream.close()
return true
}
} catch (e: java.lang.Exception) {
//file not exists
}
return exists
}
import java.nio.file.Paths;
import java.nio.file.Files;
boolean exists = Files.exists(Paths.get(URI));
Much more concise..

java.nio.file.Path for a classpath resource

Is there an API to get a classpath resource (e.g. what I'd get from Class.getResource(String)) as a java.nio.file.Path? Ideally, I'd like to use the fancy new Path APIs with classpath resources.
This one works for me:
return Path.of(ClassLoader.getSystemResource(resourceName).toURI());
Guessing that what you want to do, is call Files.lines(...) on a resource that comes from the classpath - possibly from within a jar.
Since Oracle convoluted the notion of when a Path is a Path by not making getResource return a usable path if it resides in a jar file, what you need to do is something like this:
Stream<String> stream = new BufferedReader(new InputStreamReader(ClassLoader.getSystemResourceAsStream("/filename.txt"))).lines();
The most general solution is as follows:
interface IOConsumer<T> {
void accept(T t) throws IOException;
}
public static void processRessource(URI uri, IOConsumer<Path> action) throws IOException{
try {
Path p=Paths.get(uri);
action.accept(p);
}
catch(FileSystemNotFoundException ex) {
try(FileSystem fs = FileSystems.newFileSystem(
uri, Collections.<String,Object>emptyMap())) {
Path p = fs.provider().getPath(uri);
action.accept(p);
}
}
}
The main obstacle is to deal with the two possibilities, either, having an existing filesystem that we should use, but not close (like with file URIs or the Java 9’s module storage), or having to open and thus safely close the filesystem ourselves (like zip/jar files).
Therefore, the solution above encapsulates the actual action in an interface, handles both cases, safely closing afterwards in the second case, and works from Java 7 to Java 18. It probes whether there is already an open filesystem before opening a new one, so it also works in the case that another component of your application has already opened a filesystem for the same zip/jar file.
It can be used in all Java versions named above, e.g. to list the contents of a package (java.lang in the example) as Paths, like this:
processRessource(Object.class.getResource("Object.class").toURI(),new IOConsumer<Path>(){
public void accept(Path path) throws IOException {
try(DirectoryStream<Path> ds = Files.newDirectoryStream(path.getParent())) {
for(Path p: ds)
System.out.println(p);
}
}
});
With Java 8 or newer, you can use lambda expressions or method references to represent the actual action, e.g.
processRessource(Object.class.getResource("Object.class").toURI(), path -> {
try(Stream<Path> stream = Files.list(path.getParent())) {
stream.forEach(System.out::println);
}
});
to do the same.
The final release of Java 9’s module system has broken the above code example. The Java versions from 9 to 12 inconsistently return the path /java.base/java/lang/Object.class for Paths.get(Object.class.getResource("Object.class")) whereas it should be /modules/java.base/java/lang/Object.class. This can be fixed by prepending the missing /modules/ when the parent path is reported as non-existent:
processRessource(Object.class.getResource("Object.class").toURI(), path -> {
Path p = path.getParent();
if(!Files.exists(p))
p = p.resolve("/modules").resolve(p.getRoot().relativize(p));
try(Stream<Path> stream = Files.list(p)) {
stream.forEach(System.out::println);
}
});
Then, it will again work with all versions and storage methods. Starting with JDK 13, this work-around is not necessary anymore.
It turns out you can do this, with the help of the built-in Zip File System provider. However, passing a resource URI directly to Paths.get won't work; instead, one must first create a zip filesystem for the jar URI without the entry name, then refer to the entry in that filesystem:
static Path resourceToPath(URL resource)
throws IOException,
URISyntaxException {
Objects.requireNonNull(resource, "Resource URL cannot be null");
URI uri = resource.toURI();
String scheme = uri.getScheme();
if (scheme.equals("file")) {
return Paths.get(uri);
}
if (!scheme.equals("jar")) {
throw new IllegalArgumentException("Cannot convert to Path: " + uri);
}
String s = uri.toString();
int separator = s.indexOf("!/");
String entryName = s.substring(separator + 2);
URI fileURI = URI.create(s.substring(0, separator));
FileSystem fs = FileSystems.newFileSystem(fileURI,
Collections.<String, Object>emptyMap());
return fs.getPath(entryName);
}
Update:
It’s been rightly pointed out that the above code contains a resource leak, since the code opens a new FileSystem object but never closes it. The best approach is to pass a Consumer-like worker object, much like how Holger’s answer does it. Open the ZipFS FileSystem just long enough for the worker to do whatever it needs to do with the Path (as long as the worker doesn’t try to store the Path object for later use), then close the FileSystem.
I wrote a small helper method to read Paths from your class resources. It is quite handy to use as it only needs a reference of the class you have stored your resources as well as the name of the resource itself.
public static Path getResourcePath(Class<?> resourceClass, String resourceName) throws URISyntaxException {
URL url = resourceClass.getResource(resourceName);
return Paths.get(url.toURI());
}
Read a File from resources folder using NIO, in java8
public static String read(String fileName) {
Path path;
StringBuilder data = new StringBuilder();
Stream<String> lines = null;
try {
path = Paths.get(Thread.currentThread().getContextClassLoader().getResource(fileName).toURI());
lines = Files.lines(path);
} catch (URISyntaxException | IOException e) {
logger.error("Error in reading propertied file " + e);
throw new RuntimeException(e);
}
lines.forEach(line -> data.append(line));
lines.close();
return data.toString();
}
You can not create URI from resources inside of the jar file. You can simply write it to the temp file and then use it (java8):
Path path = File.createTempFile("some", "address").toPath();
Files.copy(ClassLoader.getSystemResourceAsStream("/path/to/resource"), path, StandardCopyOption.REPLACE_EXISTING);
You need to define the Filesystem to read resource from jar file as mentioned in https://docs.oracle.com/javase/8/docs/technotes/guides/io/fsp/zipfilesystemprovider.html. I success to read resource from jar file with below codes:
Map<String, Object> env = new HashMap<>();
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
Path path = fs.getPath("/path/myResource");
try (Stream<String> lines = Files.lines(path)) {
....
}
}

Java's createNewFile() - will it also create directories?

I've got a conditional to check if a certain file exists before proceeding (./logs/error.log). If it isn't found I want to create it. However, will
File tmp = new File("logs/error.log");
tmp.createNewFile();
also create logs/ if it doesn't exist?
No.
Use tmp.getParentFile().mkdirs() before you create the file.
File theDir = new File(DirectoryPath);
if (!theDir.exists()) theDir.mkdirs();
File directory = new File(tmp.getParentFile().getAbsolutePath());
directory.mkdirs();
If the directories already exist, nothing will happen, so you don't need any checks.
Java 8 Style
Path path = Paths.get("logs/error.log");
Files.createDirectories(path.getParent());
To write on file
Files.write(path, "Log log".getBytes());
To read
System.out.println(Files.readAllLines(path));
Full example
public class CreateFolderAndWrite {
public static void main(String[] args) {
try {
Path path = Paths.get("logs/error.log");
Files.createDirectories(path.getParent());
Files.write(path, "Log log".getBytes());
System.out.println(Files.readAllLines(path));
} catch (IOException e) {
e.printStackTrace();
}
}
}
StringUtils.touch(/path/filename.ext) will now (>=1.3) also create the directory and file if they don't exist.
No, and if logs does not exist you'll receive java.io.IOException: No such file or directory
Fun fact for android devs: calls the likes of Files.createDirectories() and Paths.get() would work when supporting min api 26.

Categories

Resources