

Android端末にて内部ストレージからSDカードにファイルをコピーしたいと思っています。  
SDカードへの書き込みはSAF経由で行っています。  
書き込み後すぐにメディアスキャンなどを行いたいのですが、SDカードへの書き込み遅延により正常に読み込みできません。  
内部ストレージの場合は、sync()を使用して書き込みの完了を制御できますが、SAFでsync()を使用できますか？  
以下のコードを使用しますが、期待通りに動作しません。

[code]

    public class BinaryRename_sd {
        CountDownLatch countDownLatch;
    
        public boolean rename(DocumentFile pickedDir, String path, String new_path, ProgressDialog dialog, Context context) throws IOException {
    
            DocumentFile newFile = pickedDir.createFile("", new_path);
            for(int wait=0;wait<10;wait++){
                newFile=pickedDir.findFile(new_path);
                try {
                    if(newFile!=null){
                        wait=10;
                    }else{
                        countDownLatch = new CountDownLatch(1);
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    Thread.sleep(500);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                countDownLatch.countDown();
                            }
                        }).start();
    
                        countDownLatch.await(510, TimeUnit.MILLISECONDS);
                    }
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            FileInputStream in = new FileInputStream(path);
            double fsize = in.available();
    
            OutputStream fos=conntext.getContentResolver().openOutputStream(newFile.getUri());
    
            try {
                int len_body_read;
                int buf =1024000*1;
                byte buf_body[]=new byte[buf];
                int loaded=50;
                double degree = 0.0;
    
                while((len_body_read=in.read(buf_body))!=-1){
                    try {
                        fos.write(buf_body,0,len_body_read);
    
                        loaded=loaded+len_body_read;
                        degree = (loaded/1000*100)/(fsize/1000*2);
    
                        if(dialog!=null){
                            if((int) Math.round(degree)>95){
                                dialog.setProgress(95);
                            }else{
                                dialog.setProgress((int) Math.round(degree)+50);
                            }
                        }
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                }
    
                fos.flush();
                fos.close();
    
            }
            finally {
                in.close();
            }
    
            File delFile = new File(path);
            delFile.delete();
            delFile=null;
    
            return true;
    
        }
    
[/code]


CC BY-SA 4.0
2018-01-21T10:07:06.240
41120
2023-07-26T05:06:45.903
2021-01-05T00:45:21.337
3060
27087
question
android
SDカードへの書き込み時（SAF経由）にsync()を利用する方法


FileOutputStreamのflush()ではファイルシステムとの同期までは完了しません。  
意図したタイミングでファイルシステムとの同期を完了させる為には、やはり明示的にsyncを実行する必要があります。

以下を試してみて下さい。

**①OutputStream→FileOutputStreamに置き換え。**  
**②flushの後にsyncを実行する。**

[code]

    // サンプルコード
    try {
        FileOutputStream fos = new FileOutputStream(new File("任意のファイル"));
        fos.write(val);
        fos.flush();
        fos.getFD().sync(); // ←syncで明示的に同期する
        fos.close();    
    } catch (Exception exception){
    }
    
[/code]

頻繁にsyncを実行するとパフォーマンスが低下するので、ファイルを閉じる直前に一回実行するのがいいと思います。


CC BY-SA 3.0
2018-01-23T07:24:23.827
41149
2018-01-23T07:24:23.827
22484
41120
answer