簡體   English   中英

文檔文件隨機訪問文件

[英]DocumentFile RandomAccessFile

有沒有辦法從給定的DocumentFile獲取RandomAccessFile

我知道可以通過getUri獲得 InputStream

InputStream inputStream = getContentResolver().openInputStream(DocumentFile.getUri());

但我需要一個RandomAccessFile

謝謝你的幫助,

延斯

似乎對 SDK 21 (Lollipop) 的 SD 卡上的文件進行隨機讀/寫訪問的唯一方法如下:

import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import com.jetico.bestcrypt.FileManagerApplication;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class SecondaryCardChannel {//By analogy with the java.nio.channels.SeekableByteChannel
    private FileChannel fileChannel;
    private ParcelFileDescriptor pfd;
    private boolean isInputChannel;
    private long position;

    public SecondaryCardChannel(Uri treeUri, Context context) {
        try {
            pfd = context.getContentResolver().openFileDescriptor(treeUri, "rw");
            FileInputStream fis = new FileInputStream(pfd.getFileDescriptor());
            fileChannel = fis.getChannel();
            isInputChannel = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public int read(ByteBuffer buffer) {
        if (!isInputChannel) {
            try {
                fileChannel.close();
                FileInputStream fis = new FileInputStream(pfd.getFileDescriptor());
                fileChannel = fis.getChannel();
                isInputChannel = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            fileChannel.position(position);
            int bytesRead = fileChannel.read(buffer);
            position = fileChannel.position();
            return bytesRead;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        }
    }

    public int write(ByteBuffer buffer) {
        if (isInputChannel) {
            try {
                fileChannel.close();
                FileOutputStream fos = new FileOutputStream(pfd.getFileDescriptor());
                fileChannel = fos.getChannel();
                isInputChannel = false;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            fileChannel.position(position);
            int bytesWrite = fileChannel.write(buffer);
            position = fileChannel.position();
            return bytesWrite;
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        }
    }

    public long position() throws IOException {
        return position;
    }

    public SecondaryCardChannel position(long newPosition) throws IOException {
        position = newPosition;
        return this;
    }

    public long size() throws IOException {
        return fileChannel.size();
    }

    public SecondaryCardChannel truncate(long size) throws IOException {
        fileChannel.truncate(size);
        return this;
    }
}

從 API 級別 21(棒棒糖)開始,這可能是一個低級別的替代品:

ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "rw");
FileDescriptor fd = pfd.getFileDescriptor();
// seek to offset 10 from beginning of file
android.system.Os.lseek(fd, 10, OsConstants.SEEK_SET);

其他低級方法,如read(fd, ...)? write(fd, ...) fstat(fd)也可以在android.system.OS 中找到。

確保您有一個具有讀/寫訪問權限的 uri。

創建文本文件,其中包含要隨機打開的所有文件的路徑

in = new BufferedReader(new FileReader("randomfilepaths.txt"));

創建一個函數來獲取一個隨機文件的路徑,這可以通過readLine()來完成。

代碼:

protected String getRandomPath() {
     String returnval = null;
 try{
   if((returnval = in.readLine()) == null){
    in.close();
    moreFiles = false;
   }
 }catch(Exception e){}
 return returnval;
}

這里 returnval 將包含一個隨機文件的字符串路徑。

事實上,谷歌忘記添加這種功能或決定不添加。 因此,在使用Storage Access Framework不可能獲得RandomAccessFile

但是,如果您的代碼中需要RandomAccessFile ,則可能的話,您可以創建一個像MyRandomAccessFile這樣的超類及其基於 RandomAccessFile(和 File)或InputStreamOutputStream 的子類,您可以從DocumentFile獲取。 我使用這種方法使 JaudioTagger 適應 SAF。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM