Java Android:如何读取以字节为单位的文件?

Java Android:如何读取以字节为单位的文件?,java,android,file,Java,Android,File,我正在尝试在Android应用程序中获取以字节为单位的文件内容。我已在SD卡中获取文件,现在希望以字节获取所选文件。我在谷歌上搜索过,但没有这样的成功。请帮忙 下面是获取扩展名为的文件的代码。通过这个,我得到文件并显示在微调器中。在选择文件时,我希望获得以字节为单位的文件 private List<String> getListOfFiles(String path) { File files = new File(path); FileFilter filter =

我正在尝试在Android应用程序中获取以字节为单位的文件内容。我已在SD卡中获取文件,现在希望以字节获取所选文件。我在谷歌上搜索过,但没有这样的成功。请帮忙

下面是获取扩展名为的文件的代码。通过这个,我得到文件并显示在微调器中。在选择文件时,我希望获得以字节为单位的文件

private List<String> getListOfFiles(String path) {

   File files = new File(path);

   FileFilter filter = new FileFilter() {

      private final List<String> exts = Arrays.asList("jpeg", "jpg", "png", "bmp", "gif","mp3");

      public boolean accept(File pathname) {
         String ext;
         String path = pathname.getPath();
         ext = path.substring(path.lastIndexOf(".") + 1);
         return exts.contains(ext);
      }
   };

   final File [] filesFound = files.listFiles(filter);
   List<String> list = new ArrayList<String>();
   if (filesFound != null && filesFound.length > 0) {
      for (File file : filesFound) {
         list.add(file.getName());
      }
   }
   return list;
}
私有列表getListOfFiles(字符串路径){
文件=新文件(路径);
FileFilter=newfilefilter(){
私有最终列表exts=Arrays.asList(“jpeg”、“jpg”、“png”、“bmp”、“gif”、“mp3”);
公共布尔接受(文件路径名){
字符串扩展;
String path=pathname.getPath();
ext=路径子字符串(路径lastIndexOf(“.”+1);
返回exts.contains(ext);
}
};
最终文件[]filesFound=files.listFiles(过滤器);
列表=新的ArrayList();
如果(filesFound!=null&&filesFound.length>0){
for(文件:filesFound){
list.add(file.getName());
}
}
退货清单;
}
这里是一个简单的例子:

File file = new File(path);
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
    BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
    buf.read(bytes, 0, bytes.length);
    buf.close();
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
在manifest.xml中添加权限:

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

这里有一个解决方案,可以保证读取整个文件,不需要库,而且效率很高:

byte[] fullyReadFileToBytes(File f) throws IOException {
    int size = (int) f.length();
    byte bytes[] = new byte[size];
    byte tmpBuff[] = new byte[size];
    FileInputStream fis= new FileInputStream(f);;
    try {

        int read = fis.read(bytes, 0, size);
        if (read < size) {
            int remain = size - read;
            while (remain > 0) {
                read = fis.read(tmpBuff, 0, remain);
                System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
                remain -= read;
            }
        }
    }  catch (IOException e){
        throw e;
    } finally {
        fis.close();
    }

    return bytes;
}
byte[]fullyReadFileToBytes(文件f)引发IOException{
int size=(int)f.length();
字节字节[]=新字节[大小];
字节tmpBuff[]=新字节[大小];
FileInputStream fis=新的FileInputStream(f);;
试一试{
int read=fis.read(字节,0,大小);
如果(读取<大小){
int剩余=大小-读取;
而(保持>0){
read=fis.read(tmpBuff,0,剩余);
数组复制(tmpBuff,0,字节,大小-保留,读取);
保持-=读取;
}
}
}捕获(IOE异常){
投掷e;
}最后{
fis.close();
}
返回字节;
}

注意:它假设文件大小小于MAX_INT字节,如果需要,您可以为此添加处理

目前最简单的解决方案是使用Apache common io:

唯一的缺点是在
build.gradle
应用程序中添加此依赖项:

implementation 'commons-io:commons-io:2.5'

+1562方法计数

您也可以这样做:

byte[] getBytes (File file)
{
    FileInputStream input = null;
    if (file.exists()) try
    {
        input = new FileInputStream (file);
        int len = (int) file.length();
        byte[] data = new byte[len];
        int count, total = 0;
        while ((count = input.read (data, total, len - total)) > 0) total += count;
        return data;
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
    finally
    {
        if (input != null) try
        {
            input.close();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
    return null;
}

由于接受的
BufferedInputStream#read
不能保证读取所有内容,而不是自己跟踪缓冲区大小,因此我使用了以下方法:

    byte bytes[] = new byte[(int) file.length()];
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    DataInputStream dis = new DataInputStream(bis);
    dis.readFully(bytes);

阻塞直到完全读取完成,并且不需要额外的导入。

一个简单的InputStream就可以了

byte[] fileToBytes(File file){
    byte[] bytes = new byte[0];
    try(FileInputStream inputStream = new FileInputStream(file)) {
        bytes = new byte[inputStream.available()];
        //noinspection ResultOfMethodCallIgnored
        inputStream.read(bytes);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return bytes;
}

下面是以块形式读取整个文件的工作解决方案,以及使用scanner类读取大型文件的有效解决方案

   try {
        FileInputStream fiStream = new FileInputStream(inputFile_name);
        Scanner sc = null;
        try {
            sc = new Scanner(fiStream);
            while (sc.hasNextLine()) {
                String line = sc.nextLine();
                byte[] buf = line.getBytes();
            }
        } finally {
            if (fiStream != null) {
                fiStream.close();
            }

            if (sc != null) {
                sc.close();
            }
        }
    }catch (Exception e){
        Log.e(TAG, "Exception: " + e.toString());
    }

如果要从上下文中使用
openFileInput
方法,可以使用以下代码

这将创建一个
BufferArrayOutputStream
,并在从文件读取每个字节时将其追加

/**
*
*使用指定的上下文为文件创建InputStream
*并返回从文件中读取的字节。
*

* *@param context要使用的上下文。 *@param file要从中读取的文件。 *@返回从文件读取的字节数组,如果找不到文件,则返回null。 */ 公共静态字节[]读取(上下文,字符串文件)引发IOException{ 字节[]ret=null; if(上下文!=null){ 试一试{ InputStream InputStream=context.openFileInput(文件); ByteArrayOutputStream outputStream=新建ByteArrayOutputStream(); int nextByte=inputStream.read(); 而(下一字节!=-1){ outputStream.write(下一字节); nextByte=inputStream.read(); } ret=outputStream.toByteArray(); }捕获(忽略FileNotFoundException){} } 返回ret; }
请注意,
buf.read()
可能无法读取您请求的字节数。请参见此处的javadoc:,int,int)不要忘了在清单中。如果您要一次性读取整个文件,则无需将FileInputStream包装在BufferedInputStream中-实际上这样做会使用更多内存并降低速度,因为数据将被不必要地复制。这个答案实际上是错误的,因为第一条注释指出,尽管它的声誉很高,尽管它被接受。不幸的是,这是stackoverflow的黑暗面。@JamesKPolk关于Siavash的回答呢?是吗?谢谢。将“jsonFile”替换为“f”。使用相同的名称调用缓冲区大小和文件大小:“size”,这会让人非常困惑。这样,您的缓冲区大小将与文件大小相同,这意味着没有缓冲区,您的循环将永远不会执行。@FlorianB希望循环永远不会执行。在最佳情况下,第一次调用
fis.read(字节,0,大小)时将读取整个文件。。。循环就在那里,以防文件太大,系统无法读取整个文件,在这种情况下,我们进入循环并在对fis.read()的连续调用中读取其余文件。file.read()不能保证在一次调用中可以读取请求它的所有字节,返回值是实际读取的字节数。Dis确实帮了我很多忙为什么
BufferedInputStream#read
不能保证读取所有内容?我阅读了文档,没有发现任何关于这个“问题”的信息。更简单、更直接。谢谢
   try {
        FileInputStream fiStream = new FileInputStream(inputFile_name);
        Scanner sc = null;
        try {
            sc = new Scanner(fiStream);
            while (sc.hasNextLine()) {
                String line = sc.nextLine();
                byte[] buf = line.getBytes();
            }
        } finally {
            if (fiStream != null) {
                fiStream.close();
            }

            if (sc != null) {
                sc.close();
            }
        }
    }catch (Exception e){
        Log.e(TAG, "Exception: " + e.toString());
    }