2012-04-06 12 views
30

Próbuję uzyskać zawartość pliku w bajtach w aplikacji dla systemu Android. Mam plik na karcie SD, teraz chcę pobrać wybrany plik w bajtach. Szukałem go, ale nie miałem takiego sukcesu. Proszę pomócAndroid: jak czytać plik w bajtach?

Poniżej znajduje się kod do pobierania plików z rozszerzeniem. Przez to dostaję pliki i pokażę w spinie. Przy wyborze pliku chcę pobrać plik w bajtach.

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

Odpowiedz

73

tutaj jest prosty:

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

Dodaj zgodę na manifest.xml:

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

Zauważ, że 'buf.read()' nie może odczytać liczbę bajtów zamówionych. Zobacz javadoc tutaj: http://docs.oracle.com/javase/6/docs/api/java/io/BufferedInputStream.html#read (byte [], int, int) – vaughandroid

+1

Nie zapomnij o w manifeście. – CoolMind

+0

Jeśli zamierzasz odczytać cały plik za jednym razem, nie ma potrzeby pakowania pliku FileInputStream w BufferedInputStream - w przeciwnym razie będzie zużywać więcej pamięci i spowalniać proces, ponieważ dane będą niepotrzebnie kopiowane. – Clyde

14

Oto rozwiązanie, które gwarantuje cały plik zostanie odczytany, że nie wymaga żadnych bibliotek i jest wydajny:

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

UWAGA: zakłada się, że rozmiar pliku jest mniejszy niż MAX_INT bajtów, możesz w razie potrzeby dodać obsługę.

+1

Dzięki. Zamień "jsonFile" na "f". – CoolMind

+0

Uczynisz to bardzo zagmatwanym, wywołując rozmiar bufora i rozmiar pliku o tej samej nazwie: "rozmiar". W ten sposób będziesz miał rozmiar bufora wielkości pliku, co oznacza brak bufora, twoja pętla nigdy nie zostanie wykonana. – FlorianB

+0

@FlorianB Nadzieja jest taka, że ​​pętla nigdy nie zostanie wykonana. w najlepszym przypadku cały plik zostanie odczytany w pierwszym wywołaniu 'fis.read (bajty, 0, rozmiar);' ... pętla jest dostępna na wypadek, gdyby plik był za duży i system nie robi t przeczytać cały plik, w takim przypadku wchodzimy w pętlę i czytamy resztę w kolejnych wywołaniach fis.read(). file.read() nie gwarantuje, że wszystkie bajty, o które prosi, można odczytać w jednym wywołaniu, a wartość zwracana to liczba bajtów, RZECZYWIŚCIE odczytana. – Siavash

0

You Można również zrobić to w ten sposób:

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

Od przyjętego BufferedInputStream#read nie jest gwarantowana czytać wszystkiego, raczej niż śledzenie buforu rozmiarach siebie, użyłem tego podejścia:

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

bloki, aż pełny odczyt jest kompletny i nie wymaga dodatkowego importu.

+0

Dis bardzo mi pomógł –

0

Prosty InputStream zrobi

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