2012-04-06 73 views
30

我想在Android应用程序中获取以字节为单位的文件内容。我已经获得SD卡中的文件,现在想要以字节为单位获取所选文件。我Google搜索,但没有这样的成功。请帮助Android:如何以字节读取文件?

以下是获取带扩展名的文件的代码。通过这个我得到的文件和微调显示。在文件选择上,我想以字节为单位获取文件。

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; 
} 

回答

73

这是一个简单的:

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" /> 
+6

注意'buf.read()'可能无法读取您请求的字节数。在这里看到javadoc:http://docs.oracle.com/javase/6/docs/api/java/io/BufferedInputStream.html#read(byte [],int,int) – vaughandroid 2013-09-05 09:33:05

+1

不要忘记。 – CoolMind 2016-04-27 16:28:45

+0

如果您打算一次读取整个文件,则无需将FileInputStream包装到BufferedInputStream中,否则将会使用更多内存并减慢速度,因为数据将被不必要地复制。 – Clyde 2017-03-14 01:54:20

14

这是保证整个文件的解决方案将被读取,无需任何图书馆和效率高:

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; 
} 

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

+1

谢谢。用'f'代替'jsonFile'。 – CoolMind 2016-04-27 15:29:28

+0

您通过调用缓冲区大小和文件大小的相同名称来使它变得非常混乱:“大小”。这样你将有一个文件大小的缓冲区大小,这意味着没有缓冲区,你的循环永远不会被执行。 – FlorianB 2016-11-29 00:17:29

+0

@FlorianB希望循环不会被执行。在最好的情况下,整个文件将在第一次调用fis.read(bytes,0,size)时被读取;'......循环在那里,以防文件太大而系统不运行' t读取整个文件,在这种情况下,我们进入循环并连续读取fis.read()中的剩余内容。 file.read()不保证所有请求的字节都可以在一次调用中读取,并且返回值是ACTUALLY读取的字节数。 – Siavash 2017-03-14 07:20:20

0

您也可以这样来做:

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; 
} 
5

由于接受BufferedInputStream#read不能保证读到的一切,而不是保持缓冲区的大小跟踪我,我用这个方法:

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

块,直到完整的阅读已完成,不需要额外的进口。

+0

Dis真的帮了我很多 – 2017-08-10 15:12:38

0

一个简单的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; 
}