My CodenameOne app is being tested on the iOS simulator (iPad 8th iOS 14).
It writes some files in the private folder by means of this method:
public void writeFile() throws IOException {
try(OutputStream os = FileSystemStorage.getInstance().openOutputStream(Utils.getRootPath()+DATA_FILE);)
{
os.write(JSONText.getBytes("UTF-8"));
os.flush();
os.close();
} catch(IOException err) {
System.out.println("exception trying to write");
}
}
It works on the CN simulator (writes inside the .cn1/ folder)
but on iOS the exception is catched. The Library folder is of paramount importance on iOS.
Below is the method to get the root path
public static String getRootPath()
{
String documentsRoot=FileSystemStorage.getInstance().getRoots()[0];
String os=Display.getInstance().getPlatformName();
if (os.toLowerCase().contains("ios")) {
int pos=documentsRoot.lastIndexOf("Documents");
if (pos==-1) return documentsRoot+"/";
String libraryRoot=documentsRoot.substring(0,pos)+"Library";
String result=libraryRoot+"/";
return result;
}
The CN version of my app has to write those private files in the same location as the swift version, that is Library.
There is string manipulation, and no extra '/' are added, the file path seems legit.
So the string
file:///Users/mac/Library/Developer/CoreSimulator/Devices/alphanumeric-string/data/Containers/Data/Application/another-alphanumeric-string/Documents/
is transformed and
the getRootPath() method returns
file:///Users/mac/Library/Developer/CoreSimulator/Devices/alphanumeric-string/data/Containers/Data/Application/another-alphanumeric-string/Library/
But there is exception.
Furthermore, at some point after the writing attempt, I see in the console output something I think is relevant:
Failed to create directory /Users/mac/Library/Developer/CoreSimulator/Devices/alphanumeric-string/data/Containers/Data/Application/another-alphanumeric-string/Documents/cn1storage/
What is this? Is it related to my problem?
Is CN filesystem access broken or flawed?
I know io access permissions are automatically created by the CN compiler, but are they working?
So how to fix my issue about the Library folder?
The cn1storage printout just means the storage directory already exists.
The way to get the library path is this: Getting an iOS application's "~/Library" path reliably
You need to use that approach. I think your assumption that Document and Library reside under the exact same hierarchy is just incorrect.
Related
Java is the key here. I need to be able to delete files but users expect to be able to "undelete" from the recycle bin. As far as I can tell this isn't possible. Anyone know otherwise?
Ten years later, with Java 9, finally there is a builtin way to move files to the Trash Bin
java.awt.Desktop.moveToTrash(java.io.File):
public boolean moveToTrash(File file)
Moves the specified file to the trash.
Parameters:
file - the file
Returns:
returns true if successfully moved the file to the trash.
The availability of this feature for the underlying platform can be tested with Desktop.isSupported(Desktop.Action.MOVE_TO_TRASH).
For various reasons Windows has no concept of a folder that simply corresponds to the Recycle Bin.
The correct way is to use JNI to invoke the Windows SHFileOperation API, setting the FO_DELETE flag in the SHFILEOPSTRUCT structure.
SHFileOperation documention
Java example for copying a file using SHFileOperation (the Recycle Bin link in the same article doesn't work)
Java 9 has new method but in my case I am restricted to Java 8.
I found Java Native Access Platform that has hasTrash() and moveToTrash() method. I tested it on Win 10 and Mac OS (Worked) for me.
static boolean moveToTrash(String filePath) {
File file = new File(filePath);
FileUtils fileUtils = FileUtils.getInstance();
if (fileUtils.hasTrash()) {
try {
fileUtils.moveToTrash(new File[] { file });
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} else {
System.out.println("No Trash");
return false;
}
}
Maven Repository
https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform/5.1.0
Don't confuse It is Java Native Access Platform not Java Native Access
See the fileutil incubator project (part of the Java Desktop Integration Components project):
This incubator project is created to host those file utility functionalities, most of which are extensions to the java.io.File class in J2SE. There are frequent requests from Java developers for such features like: sending a file to trash bin, checking free disk space, accessing file attributes etc. This project addresses such frequently requested APIs.
Note, this should work not only on Windows, but on other platforms (Linux, Mac OS X) as well.
My 3 cents - use cmd util Recycle.exe with -f to force recycle (no prompt). Works perfectly.
public class Trash {
public void moveToTrash(File ... file) throws IOException {
moveToTrash(false, file);
}
public void promptMoveToTrash(File ... file) throws IOException {
moveToTrash(true, file);
}
private void moveToTrash(boolean withPrompt, File ... file) throws IOException {
String fileList = Stream.of(file).map(File::getAbsolutePath).reduce((f1, f2)->f1+" "+f2).orElse("");
Runtime.getRuntime().exec("Recycle.exe "+(withPrompt ? "" : "-f ")+fileList);
}
}
In JNA platform, the FileUtils doesn't use Win32 API. You should prefer W32FileUtils which supports Undo (restore the file from recycle bin).
Edit: as of the current version of JNA Platform (5.7.0), with FileUtils.getInstance(), this statement has become incorrect, and FileUtils will use the Win32 API.
I'm programming an app for android using libgdx and simplexml to load the levels. Now I want to load the level1.xml file which is located at the android assets file but I don't know how to get the correct path to it. This is my code:
private Level currentLevel;
...
loadLevel(1);
...
private void loadLevel(int level) {
String path = Gdx.files.internal("level" + level +".xml").path();
try {
InputStream source = new FileInputStream(path);
Serializer serializer = new Persister();
currentLevel = serializer.read(Level.class, source);
} catch (Exception e) {
e.printStackTrace();
}
}
But the path I get is just "level1.xml". I know how to do this with
InputStrem source = getAssets().open("level1.xml");
Because I'm doing this in my core-module I can't use the android libraries and I want use my app on windows/linux/html too.
I hope my question is understandable. Thanks for your help!
In case of internal (read only, packed with the app, as it seems to be in your question) your files should be located at "project/android/assets", (or "project/core/assets" if not targeting android backend) and you can load them using Gdx.files.internal(), so in this case, it would be
Gdx.files.internal("level1.xml")
It will return a FileHandle, you can read the content as string directly using
Gdx.files.internal("level1.xml").readString();
Remember to set the working directory of your desktop project to "project/android/assets"
I recomend you to read the wiki, it explains it very detailed here
You can access file in assets like this
"file:///android_asset/level1.xml"
I migrated my project from Net beans 6.9.1 to Net Beans 7.3.1 and faced this annoying error a red exclamation icon on a random file jsp or java .
I opened them and did not find any error.
I tried some suggestions after searching Google to disable html and jsp validation with no luck , another suggestion was to delete the cache files under user directory folder cache at C:\Users\home\.netbeans\6.9\var\cache and also without luck !!!
resolve bug incomplete
sample of java file error
You can try to do the following ... it worked for me
rename the file of jsp or java to make the error go away for example
test.java renamed to test_.java and then renamed back to test.java
also same for jsp or xml
references
translate it to english
By working with netbenas on some projects in some of these projects
netbeans files mark some files with the symbol of admiration and the
message "Error parsing file". This occurs because of a problem
netbenas cache. The solution to this is to close the netbenas, clean
(delete cache files and start the netbenas will return. Here are the
different routes of some operating systems cache. WINDOWS: C: \ Users
\ AppData \ Local \ NetBeans \ Cache \ 7.2 \ MAC OS X: / Users //
Library/Caches/NetBeans/7.2 / UNIX: / home // .cache/netbeans/7.2
good luck
i fixed "Error Parsing File" in my Java file (IDE: Netbeans) by just deleting the space before the bottom most "}" and press enter. Basically, just do some modification in the file and save it again.
In my case I had a class similar to the following and Netbeans (8.2) showed no error inside the file, but in the file icon it showed a error of parsing the file:
public class FileUploadUtil {
private static interface WriteToFile {
public void run(File file) throws IOException;
}
private static interface UseFile {
public void run(File file) throws IOException;
}
private static void createAndUseTempFile(InputStream is, UseFile use) throws IOException {
createAndUseTempFile((file) -> {
try (FileOutputStream fos = new FileOutputStream(file)) {
byte[] bytes = new byte[1024];
int read;
while ((read = is.read(bytes)) != -1) {
fos.write(bytes, 0, read);
}
fos.flush();
}
}, use, "tmp");
}
private static void createAndUseTempFile(Image image, UseFile use, String extension) throws IOException {
createAndUseTempFile((file) -> image.writeToFile(file), use);
}
private static void createAndUseTempFile(WriteToFile write, UseFile use, String extension) throws IOException {
File file = null;
try {
String key = System.currentTimeMillis() + "-" + SecurityUtil.generateUUID();
String suffix = (extension != null) ? ("." + extension) : null;
file = File.createTempFile(key, suffix);
write.run(file);
use.run(file);
} finally {
if (file != null) {
file.delete();
}
}
}
}
The method:
private static void createAndUseTempFile(Image image, UseFile use, String extension) throws IOException {
createAndUseTempFile((file) -> image.writeToFile(file), use);
}
should be:
private static void createAndUseTempFile(Image image, UseFile use, String extension) throws IOException {
createAndUseTempFile((file) -> image.writeToFile(file), use, extension);
}
but Netbeans showed no errors inside the file, so I tried to reload the project, rename the file and so on.
Then I tried to compile with gradle and received the error:
FileUploadUtil.java:95: error: incompatible types: InputStream is not a functional interface
Then I realized that it was trying to call createAndUseTempFile(InputStream is, UseFile use) instead of createAndUseTempFile(WriteToFile write, UseFile use, String extension), but because the InputStream is not a functional interface and doesn't extends/implements an interface that has a method that receives a File, it couldn't call that method (and shouldn't!).
I think it's a Netbeans bug in this case, because it should show the error in that line.
Sometimes I had these issues with embedded JavaScripts in the JSP files, especially if the JavaScript parts contained JSTL EL expressions. In these cases the NetBeans project tree view showed a red exclamation mark ("Error parsing file") for the JSP file but when opening the file it didn't show a single error for a line.
Idea 1: Add HTML comments to the JavaScript part in order to make the JSP/HTML syntax highlighter engine ignore these parts:
<b>Very primitive example</b>
<script type="text/javascript">// <!--
var foo = ${myBean.bar}; // -->
</script>
Idea 2: Put as much JavaScript code as possible into external JS files. In general it's a good idea to avoid JavaScript code in JSP/HTML files as this allows you to use additional anti XSS measures like X-XSS-Protection.
May occur if having unnecessary lambda return statement in Netbeans 8.2
I'm not sure if this is helpful but I was using netBeans IDE 8.2 and one of my Dialogs exampleDialog.java showed a redmark on it and there were no errors in the file.
I was using Dimension wndSize;
wndSize = theKit.getScreenSize();
and in setting the window size I was using wndSize.getWidth(); and wndSize.getHeight(); these were wrong I changed them to wndSize.width; and wndSize.height;
and the red mark disappeared.
regards Michael.
No need to worry ! This is because after you make any changes in servets or jsp you need to save your file.
So first save your file then everything goes well.
This worked for me!
I have a file called Gate.IC inside my assets in my Android App.
I use this code to measure the length of the file in the assets:
private byte[] Buf = new byte[1024*512];
public int FileLength (String s)
{
int Count = 0;
try {
InputStream s2 = assetManager.open(s);
int tmp = 0;
while ((tmp=s2.read(Buf))>0)
Count+=tmp;
s2.close();
}
catch (IOException e) {
String Message = e.getMessage();
}
return Count;
}
This code works fine for all files except this one.
When it gets to this file, it does open it(and shows the correct file length), but when it reads it I get an IOException and the LogCat says "Error reading asset data" and then "Unable to access asset data: -1"
If I take a different file and change it's name to Gate.IC and don't have the actual Gate.IC file in the assets, it works.
If I change the name of the original Gate.IC into another asset's name, then I get the same error with the "cover" name.
I don't know what it is in this file that it just can't read it.
Here is the Rogue file:
https://dl.dropbox.com/u/8025882/RPG/Gate.IC
you can use this for getting length of the file:
getAssets().openFd( "filename" ).getLength();
I have solved the issue.
Well as I mentioend, it turns out ADT or the Android SDK packaging would compress some fo the assets. My file being my own custom format would be compressed.
Once your file is compressed you cannot read it the same way I did.
There is a program in Android SDK called aapt.exe. It does the packaging of the assets.
All you need to do is call this command with the flag -0 .
Sounds simple, right?
The issue is that eclipse does not let you add flags to this command from within the ADT plugin.
You need to either edit the Android SDK XML build files, or to replace aapt.exe with your own program that calls the original aapt.exe program with the flags you want.
I did the latter.
Here is my devblog entry about it.
http://pompidev.net/2012/10/27/unable-to-access-asset-data-1-and-compressed-assetsandroid/
First time posting here, will try to be succinct. This is a classic 'can't access file within an Applet' problem, but I'm having a particular difficulty with it.
I'm trying to rewrite this file:
A JavaSound test for libpd
into a template applet to load libpd (https://github.com/libpd/libpd) patches made in PureData (puredata.info)...this already works in a normal Main function in a non-applet Java program (see above), where the main function finds the patch using:
PdBase.openAudio(0, outChans, (int) sampleRate);
int patch = PdBase.openPatch("samples/com/noisepages/nettoyeur/libpd/sample/test.pd");
PdBase.computeAudio(true);
The reason it tries to load the path and file into a int variable is that the core function itself does this with:
public synchronized static int openPatch(File file) throws IOException {
if (!file.exists()) {
throw new FileNotFoundException(file.getPath());
}
String name = file.getName();
File dir = file.getParentFile();
long ptr = openFile(name, (dir != null) ? dir.getAbsolutePath() : ".");
if (ptr == 0) {
throw new IOException("unable to open patch " + file.getPath());
}
int handle = getDollarZero(ptr);
patches.put(handle, ptr);
return handle;
}
public synchronized static int openPatch(String path) throws IOException {
return openPatch(new File(path));
}
This is because PD tries to identify each patch by giving an int 'handle' (dollarZero, for legacy reasons), so that int handle gets passed around to open and close the patch file.
So now. I'm trying to load the same file in an Applet, so since I believe it runs 'in the client' and won't know what path I'm talking about, I read up on java.net.URL and tried to build variations of:
patchURL = new URL("test.pd");
PdBase.openPatch(patchURL.getPath().toString());
and
URL url = this.getClass().getResource("test.pd");
inspired by previous questionsin the init() and start() functions of the applet, turning the original main into a local static method sound().
All I get is null pointers. I would've thought all I needed was a simple getDocumentBase(), but can't seem to make it work. Anyone?
libpd is just a thin wrapper on top of Pure Data, and Pure Data doesn't know about URLs or input streams in Java. The openPatch method merely sends the patch name and directory to Pd, and then Pd will try to open the corresponding file. So, applets are out, unless you're willing to tinker with security policies.
About finding files, the simple sample program is part of the libpd Eclipse project. It's meant to be run in Eclipse, and the hard-coded path to the patch is relative to the project root in Eclipse. If you want your code to run in a different setting, you have to adjust your paths accordingly.