0

I am making a file backup program, using ACTION_OPEN_DOCUMENT_TREE my user picks a folder, then my intent is to copy all items in that folder to the tablet, I do this by saving the URI of the folder the user selects in variable TheURI, I then iterate between all files in the folder by the following

    DocumentFile documentFile = DocumentFile.fromTreeUri(this, TheURI);
        for (DocumentFile file : documentFile.listFiles()) {
            Log.i("",file.getName());
            if(file.isDirectory()){
                Log.i("","is a Directory");
            }else{
                if(file.canRead()||file.canWrite()){
                    savefile(file.getUri());
                }
                Log.i("","is not a Directory");
            }

            Log.i("file.canRead(): " , String.valueOf(file.canRead()));
            Log.i("file.canWrite(): " , String.valueOf(file.canWrite()));

            Log.i("", String.valueOf(file.getUri()));
        }

My savefile function uses SimpleStorage api to grab the absolute file path as follows:

    DocumentFile Filename = DocumentFileCompat.fromUri(this, sourceuri);
        DocumentFileUtils.copyFileTo(Filename, this, "/sdcard/Left", null, new FileCallback() {
            @Override
            public void onConflict(@NotNull DocumentFile destinationFile, @NotNull FileCallback.FileConflictAction action) {
                // do stuff
            }

            @Override
            public void onCompleted(@NotNull Object result) {
                if (result instanceof DocumentFile) {
                    // do stuff
                } else if (result instanceof MediaFile) {
                    // do stuff
                }
            }

            @Override
            public void onReport(Report report) {
                Log.d("%s", String.valueOf(report.getProgress()));
            }

            @Override
            public void onFailed(ErrorCode errorCode) {
                Log.d("Error: %s", errorCode.toString());
            }
        });

I am copying a 500mb file to a tablet that has 20gb of free storage however I get the error

D/Error: %s: NO_SPACE_LEFT_ON_TARGET_PATH

Josh Hunter
  • 45
  • 1
  • 10
  • You are copying to the tablet you say. To which tablet? And what would be the target path? You realise that you call savefile for every file in the choosen ditectory and that you can have called it a hundred times before the first file starts to copy or the first file is copied? – blackapps Nov 21 '22 at 15:57
  • `if(file.canRead()||file.canWrite())` Fir a copy read is enough. – blackapps Nov 21 '22 at 16:01
  • `api to grab the absolute file path as follows:` The absolute file path of what? From what is it grabbed? – blackapps Nov 21 '22 at 16:02
  • `DocumentFile Filename = ....` Please dont name your DocumentFile variable 'FileName'. Unreadable code! – blackapps Nov 21 '22 at 16:04
  • To answer your first problem, yes I understand that, I am currently using a dummy drive for testing purposes with one file on it, the only file on the drive is trimmedtram.mp4. (I understand I will need to change this in the future, this is just for testing.) – Josh Hunter Nov 21 '22 at 16:04
  • `DocumentFileUtils.copyFileTo(Filename` We dont know that function. If it gives problems you should post the code. But better just post simple code to copy the bytes from uri to file . No callbacks or whatever. – blackapps Nov 21 '22 at 16:07
  • `To answer your first problem` Sorry, i have no problem. You have a problem. I just try to help you. – blackapps Nov 21 '22 at 16:10
  • ```DocumentFileUtils.copyFileTo``` is part of the SimpleStorageAPI I am using. If there is a way to copy the bytes from uri to file I am unaware of it so please point me in that direction. When I attempt to use Java I/O I get a different error stating that the file I reference is null – Josh Hunter Nov 21 '22 at 16:11
  • For the time beeing throw away this simple api stuff. Just copy the file from a source uri to a file path. This is basic stuff. You can find examples all over the internet. InputStream. OutputStream. In a loop: Read bytes from input stream. Write the bytes to outputstream. Just like an ordinary file copy. Make your own copy function. – blackapps Nov 21 '22 at 16:14
  • When I do this, I get ```ENOENT (No such file or directory)``` I will update my post with my BufferedInputStream so you can tell me if there are any errors with it. @blackapps – Josh Hunter Nov 21 '22 at 16:22
  • `if (!dir.exists()) if(!dir.mkdirs()) return;` Check the return value of mkdirs() and handle accordingly. I leave it to you to add a Toast() to inform the user. Please adapt your code here too. – blackapps Nov 21 '22 at 16:51
  • `String sourceFilename = DocumentFileUtils.getAbsolutePath(Filename,this);` That is nonsense code. Do away with thise utils. You dont need them. And give your DicumentFile variable a different name. I asked that before. Better remive the whole DicumentFike variable as you do not need it to open an inputstream for your uri. Open the stream at the first line of your save function. – blackapps Nov 21 '22 at 16:54
  • I've found and posted a solution, thank you for pointing me towards ACTION_OPEN_DOCUMENT_TREE as without that I would not have found interactions with URI and DocumentFile. – Josh Hunter Nov 21 '22 at 17:03

1 Answers1

0

solution found!

When writing to a directory, "/sdcard/" is not a valid path (Most absolute paths aren't) however, if you point directly to the primary storage, which should always be in 'storage/emulated/0' then there will be space. This is pointed out in the SimpleStorage readme, I just missed it!

Turns out grabbing the absolute path still requires you to specify that you're putting it in emulated, because self is always treat as full

Josh Hunter
  • 45
  • 1
  • 10