wake-up-neo.com

Wie kann eine Datei aus dem internen App-Speicher in einen externen Speicher auf Android verschoben oder umbenannt werden?

Ich lade Dateien aus dem Internet herunter und speichere die Streaming-Daten in einer temporären Datei im internen Speicher meiner App, die von getFilesDir () bereitgestellt wird.

Sobald der Download abgeschlossen ist, muss ich die temporäre Datei in mein Downloadverzeichnis im externen Speicher (normalerweise eine SD-Karte) verschieben. Aus irgendeinem Grund funktioniert File.renameTo () jedoch nicht. Ich vermute, es gibt ein Problem, weil es zwei separate Dateisysteme gibt, ich kann jedoch immer noch direkt auf die SD-Karte herunterladen, und die Datei-URIs sind korrekt.

Gibt es eine andere einfache und schnelle Möglichkeit, diese Datei vom internen Speicher in den externen Speicher zu übertragen, oder muss ich einen Byte-Stream kopieren und das Original löschen?

33

So kopieren Sie Dateien vom internen Speicher auf die SD-Karte und umgekehrt, indem Sie folgenden Code verwenden:

public static void copyFile(File src, File dst) throws IOException
{
    FileChannel inChannel = new FileInputStream(src).getChannel();
    FileChannel outChannel = new FileOutputStream(dst).getChannel();
    try
    {
        inChannel.transferTo(0, inChannel.size(), outChannel);
    }
    finally
    {
        if (inChannel != null)
            inChannel.close();
        if (outChannel != null)
            outChannel.close();
    }
}

Und es funktioniert...

80
barmaley

Interner und externer Speicher sind zwei verschiedene Dateisysteme. Deshalb schlägt renameTo () fehl.

Sie müssen die Datei kopieren und das Original löschen

12
Jacob Nordfalk

Vergessen Sie nicht, die Datei der Galerie des Geräts zu zeigen, nachdem Sie die Datei kopiert haben (wie in @barmaley 's große Antwort zeigt), damit der Benutzer sie später anzeigen kann. 

Der Grund, warum es manuell gemacht werden muss, ist das

Android führt einen vollständigen Medienscan nur beim Neustart und beim (erneuten) Einhängen von .__ durch. die SD-Karte

(wie dieser Leitfaden zeigt).

Der einfachste Weg, dies zu tun, ist das Senden einer Broadcast-Nachricht für den Scanvorgang: 

Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(outputFile));
context.sendBroadcast(intent);

Und voila! Sie können Ihre Datei jetzt in der Galerie des Geräts anzeigen.

10
limlim

Eine Alternative zum Kopieren mit Ihrer eigenen Funktion ist die Verwendung der Klasse "FileUtils" der Bibliothek von Apache in der Funktion copyFile :

FileUtils.copyFile(src, dst, true);
3

Stellen Sie sich das vor: 

  • Dies ist ein interner Pfad: pathInternal 
  • Und dies ist ein externer Pfad: PathExternal

Versuchen Sie es mit diesem Code: 

public void moveIn (String pathInternal, String pathExternal) {
    File fInternal = new File (pathInternal);
    File fExternal = new File (pathExternal);
    if (fInternal.exists()) {
        fInternal.renameTo(fExternal);
    }
}
0

Sie können dies mit Operationen mit byte []

definiere in deiner Klasse:

    public static final String DATA_PATH = 
Environment.getExternalStorageDirectory().toString() + "/MyAppName/";

dann:

AssetManager assetManager = context.getAssets();
InputStream in = assetManager.open("data/file.txt");

OutputStream out = new FileOutputStream(DATA_PATH + "data/file.txt");

// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;

while ((len = in.read(buf)) > 0) {
    out.write(buf, 0, len);
}
in.close();
out.close();
0
Yuliia Ashomok

Hat einige geringfügige Änderungen an @ barmaleys Code vorgenommen

public boolean copyFile(File src, File dst) {
    boolean returnValue = true;

   FileChannel inChannel = null, outChannel = null;

    try {

        inChannel = new FileInputStream(src).getChannel();
        outChannel = new FileOutputStream(dst).getChannel();

   } catch (FileNotFoundException fnfe) {

        Log.d(logtag, "inChannel/outChannel FileNotFoundException");
        fnfe.printStackTrace();
        return false;
   }

   try {
       inChannel.transferTo(0, inChannel.size(), outChannel);

   } catch (IllegalArgumentException iae) {

         Log.d(logtag, "TransferTo IllegalArgumentException");
         iae.printStackTrace();
         returnValue = false;

   } catch (NonReadableChannelException nrce) {

         Log.d(logtag, "TransferTo NonReadableChannelException");
         nrce.printStackTrace();
         returnValue = false;

   } catch (NonWritableChannelException nwce) {

        Log.d(logtag, "TransferTo NonWritableChannelException");
        nwce.printStackTrace();
        returnValue = false;

   } catch (ClosedByInterruptException cie) {

        Log.d(logtag, "TransferTo ClosedByInterruptException");
        cie.printStackTrace();
        returnValue = false;

   } catch (AsynchronousCloseException ace) {

        Log.d(logtag, "TransferTo AsynchronousCloseException");
        ace.printStackTrace();
        returnValue = false;

   } catch (ClosedChannelException cce) {

        Log.d(logtag, "TransferTo ClosedChannelException");
        cce.printStackTrace(); 
        returnValue = false;

    } catch (IOException ioe) {

        Log.d(logtag, "TransferTo IOException");
        ioe.printStackTrace();
        returnValue = false;


    } finally {

         if (inChannel != null)

            try {

               inChannel.close();
           } catch (IOException e) {
               e.printStackTrace();
           }

        if (outChannel != null)
            try {
                outChannel.close();
           } catch (IOException e) {
                e.printStackTrace();
           }

        }

       return returnValue;
    }
0
user2903200