Zoeken…


Invoering

Bestanden lezen en schrijven in Android verschillen niet van bestanden lezen en schrijven in standaard Java. Hetzelfde java.io pakket kan worden gebruikt. Er is echter een specifiek verband met de mappen waarin u mag schrijven, machtigingen in het algemeen en MTP werken er omheen.

Opmerkingen

Android biedt middelen voor het delen van het bestand tussen meerdere applicaties zoals hier gedocumenteerd. Dit is niet vereist als er slechts één app is die het bestand maakt en gebruikt.

Android biedt alternatieve opslagopties zoals gedeelde en privé-voorkeuren, opgeslagen bundels en ingebouwde database. In sommige gevallen zijn ze een betere keuze dan alleen het gebruik van gewone bestanden.

Android-activiteit heeft weinig specifieke methoden die eruit zien als vervangingen van de standaard Java IO-methoden. Bijvoorbeeld, in plaats voor File.delete() kunt u bellen Context.deleteFile() , en in plaats van het toepassen van File.listFiles() recursief u kunt bellen Context.fileList() om de lijst met al uw app specifieke bestanden te komen met iets minder code. Ze bieden echter geen extra functionaliteit buiten het standaard java.io pakket.

De werkmap verkrijgen

U kunt uw werkmap verkrijgen door de methode getFilesDir() op uw activiteit aan te roepen (Activiteit is de centrale klasse in uw toepassing die overneemt van Context. Zie hier ). Lezen is niet anders. Alleen uw toepassing heeft toegang tot deze map.

Uw activiteit kan bijvoorbeeld de volgende code bevatten:

  File myFolder = getFilesDir();
  File myFile = new File(myFolder, "myData.bin");

Ruwe reeks bytes schrijven

  File myFile = new File(getFilesDir(), "myData.bin");
  FileOutputStream out = new FileOutputStream(myFile);

  // Write four bytes one two three four:
  out.write(new byte [] { 1, 2, 3, 4}
  out.close()

Er is niets specifiek voor Android met deze code. Als u vaak veel kleine waarden schrijft, gebruikt u BufferedOutputStream om de slijtage van de interne SSD van het apparaat te verminderen.

Het object in serie plaatsen

De oude goede Java-objectserialisatie is voor u beschikbaar in Android. u kunt Serializable-klassen definiëren zoals:

  class Cirle implements Serializable {
    final int radius;
    final String name;

    Circle(int radius, int name) {
      this.radius = radius;
      this.name = name;
    }
  }

en schrijf vervolgens naar de ObjectOutputStream:

  File myFile = new File(getFilesDir(), "myObjects.bin");
  FileOutputStream out = new FileOutputStream(myFile);
  ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(out));

  oout.writeObject(new Circle(10, "One"));
  oout.writeObject(new Circle(12, "Two"));
  
  oout.close()

Java-objectserialisatie kan een perfecte of echt slechte keuze zijn, afhankelijk van wat u ermee wilt doen - buiten het bereik van deze zelfstudie en soms op meningen gebaseerd. Lees eerst over de versiebeheer als u besluit deze te gebruiken.

Schrijven naar externe opslag (SD-kaart)

U kunt ook lezen en schrijven van / naar geheugenkaart (SD-kaart) die aanwezig is in veel Android-apparaten. Bestanden op deze locatie zijn toegankelijk voor andere programma's, ook rechtstreeks door de gebruiker nadat het apparaat via een USB-kabel op de pc is aangesloten en het MTP-protocol is ingeschakeld.

Het vinden van de locatie van de SD-kaart is iets problematischer. De klasse Environment bevat statische methoden om "externe mappen" te krijgen die normaal in de SD-kaart moeten zitten, ook informatie als de SD-kaart überhaupt bestaat en beschrijfbaar is. Deze vraag bevat waardevolle antwoorden om ervoor te zorgen dat de juiste locatie wordt gevonden.

Toegang tot externe opslag vereist machtigingen in uw Android-manifest:

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

Voor oudere versies van Android-machtigingen volstaat het om deze machtigingen te manifesteren (de gebruiker moet tijdens de installatie goedkeuren). Vanaf Android 6.0 vraagt Android de gebruiker echter om goedkeuring op het moment van de eerste toegang en u moet deze nieuwe aanpak ondersteunen. Anders wordt toegang geweigerd, ongeacht uw manifest.

In Android 6.0 moet u eerst op toestemming controleren en deze vervolgens, indien niet verleend, aanvragen. De codevoorbeelden zijn te vinden in deze SO-vraag .

Het probleem 'Onzichtbare MTP-bestanden' oplossen.

Als u bestanden maakt voor export via USB-kabel naar desktop met behulp van het MTP-protocol, kan het een probleem zijn dat nieuw gemaakte bestanden niet onmiddellijk zichtbaar zijn in de bestandsverkenner op de aangesloten desktop-pc. Om nieuwe bestanden zichtbaar te maken, moet u MediaScannerConnection bellen:

File file = new File(Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_DOCUMENTS), "theDocument.txt");
FileOutputStream out = new FileOutputStream(file)

... (write the document)

out.close()
MediaScannerConnection.scanFile(this, new String[] {file.getPath()}, null, null);
    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
            Uri.fromFile(file)));

Deze MediaScannerConnection-oproepcode werkt alleen voor bestanden, niet voor mappen. Het probleem wordt beschreven in dit Android-bugrapport . Dit kan in de toekomst voor sommige versies of op sommige apparaten worden opgelost.

Werken met grote bestanden

Kleine bestanden worden in een fractie van een seconde verwerkt en u kunt ze lezen / schrijven in plaats van de code waar u dit nodig hebt. Als het bestand echter groter is of anderszins langzamer kan worden verwerkt, moet u mogelijk AsyncTask in Android gebruiken om met het bestand op de achtergrond te werken:

    class FileOperation extends AsyncTask<String, Void, File> {

        @Override
        protected File doInBackground(String... params) {
          try {
            File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOCUMENTS), "bigAndComplexDocument.odf");
            FileOutputStream out = new FileOutputStream(file)

           ... (write the document)

            out.close()
            return file;
            } catch (IOException ex) {
               Log.e("Unable to write", ex);
               return null;
              }
        }

        @Override
        protected void onPostExecute(File result) {
          // This is called when we finish 
        }

        @Override
        protected void onPreExecute() {
           // This is called before we begin
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            // Unlikely required for this example
        }
    }
}

en toen

new FileOperation().execute("Some parameters");    

Deze SO-vraag bevat het volledige voorbeeld over het maken en aanroepen van de AsyncTask. Zie ook de vraag over foutafhandeling over het omgaan met IOExceptions en andere fouten.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow