Frage

Ich werde verrückt, habe ich ein Datei-Objekt, so kann es mit Object gelesen werden, und ich legte das Vermögen Ordner. Das Verfahren arbeitet mit einer Datei kleiner als 1 M, und gibt Fehler bei größeren Dateien. Ich las, dass eine Grenze von Android-Plattform ist, aber ich weiß auch, dass seine „leicht“ vermieden. Diejenigen, die das Spiel Reging Donner heruntergeladen haben, zum Beispiel, kann leicht erkennen, dass in ihr Vermögen Ordner eine Datei 18,9 Mio. groß ist. Dies ist mein Code für Lese 1 Objekt aus einem ObjecInputStream

File f = File.createTempFile("mytempfile", "dat");
FileOutputStream fos = new FileOutputStream(f);

InputStream is = mc.getAssets().open(path,3);

ObjectInputStream ois=new ObjectInputStream(is);
byte[] data = (byte[]) ois.readObject();
fos.write(data);

fos.flush();
fos.close();
ois.close();
is.close();

Jetzt habe ich eine nicht komprimierte Datei, und ich kann es verwenden, ohne sich Gedanken über die Fehlermeldung „Diese Datei kann nicht als Dateideskriptor geöffnet werden kann, ist es wahrscheinlich komprimiert“

Diese Funktion funktioniert gut mit Dateien kleiner als 1 M, mit größeren Dateien zurückgeben eine java.io.IOException on line "Object ois = new Object (ist),"

warum ??

War es hilfreich?

Lösung

das gleiche Problem konfrontiert. Ich habe meine 4MB-Datei in 1 MB Stücke zerschneiden und auf dem ersten Laufe werde ich Mitglied der Stücke in einen Datenordner auf dem Handy. Als zusätzlichen Bonus wird die APK richtig komprimiert. Die Chunk-Dateien werden als 1.db, 2.db usw. Der Code lautet wie folgt:

File Path = Ctxt.getDir("Data", 0);
File DBFile = new File(Path, "database.db");

if(!DBFile.exists() || DatabaseNeedsUpgrade)  //Need to copy...
    CopyDatabase(Ctxt, DBFile);


static private void CopyDatabase(Context Ctxt, File DBFile) throws IOException
{
    AssetManager assets = Ctxt.getAssets();
    OutputStream outstream = new FileOutputStream(DBFile);
    DBFile.createNewFile();
    byte []b = new byte[1024];
    int i, r;
    String []assetfiles = assets.list("");
    Arrays.sort(assetfiles);
    for(i=1;i<10;i++) //I have definitely less than 10 files; you might have more
    {
        String partname = String.format("%d.db", i);
        if(Arrays.binarySearch(assetfiles, partname) < 0) //No such file in assets - time to quit the loop
            break;
        InputStream instream = assets.open(partname);
        while((r = instream.read(b)) != -1)
            outstream.write(b, 0, r);
        instream.close();
    }
    outstream.close();
}

Andere Tipps

Die Begrenzung ist auf Druckanlagen. Wird der Vermögenswert nicht komprimiert ist, Kartenspeicher-System kann die Datendatei und das virtuelle Linux-Speicher-Paging-System verwenden Pull-in oder verwerfen 4K Brocken als angemessen. (Das „Zipalign“ Tool stellt sicher, dass unkomprimierte Vermögen Wort ausgerichtet in der Datei, das heißt, sie auch im Speicher ausgerichtet wird, werden, wenn sie direkt abgebildet.)

Wenn der Vermögenswert komprimiert wird, muss das System die ganze Sache in dem Speicher dekomprimieren. Wenn Sie ein 20 MB Asset haben, ist, dass Mittel 20 MB des physischen Speichers durch Ihre Anwendung gebunden.

Im Idealfall würde das System eine Art von Fenstern Kompression verwenden, so dass nur Teile müssen vorhanden sein, aber das erfordert einige fanciness in dem Asset-API und ein Komprimierungsschema, das gut mit Direktzugriff funktioniert. Gerade jetzt APK == Zip mit "entleeren" Kompression, so dass die nicht praktikabel ist.

Sie können Ihr Vermögen unkomprimiert halten, indem ihnen ein Suffix von einem Dateityp geben, die nicht komprimiert werden (zum Beispiel „.png“ oder“.mp3" ). Sie können sie auch mit „zip -0“ statt während des Build-Prozess manuell in der Lage hinzufügen von mit ihnen durch aapt bis gebündelt. Dies wird wahrscheinlich die Größe Ihrer APK erhöhen.

Wie Seva vorgeschlagen, dass Sie Ihre Datei in Stücke aufteilen kann. Ich habe diese meine 4MB Datei aufteilen

public static void main(String[] args) throws Exception {  
    String base = "tracks";  
    String ext = ".dat";  
    int split = 1024 * 1024;  
    byte[] buf = new byte[1024];  
    int chunkNo = 1;  
    File inFile = new File(base + ext);  
    FileInputStream fis = new FileInputStream(inFile);  
    while (true) {  
      FileOutputStream fos = new FileOutputStream(new File(base + chunkNo + ext));  
      for (int i = 0; i < split / buf.length; i++) {  
        int read = fis.read(buf);  
        fos.write(buf, 0, read);  
        if (read < buf.length) {  
          fis.close();  
          fos.close();  
          return;  
        }  
      }  
      fos.close();  
      chunkNo++;  
    }  
  }  

Wenn Sie nicht wieder die Dateien in eine einzige Datei auf dem Gerät verbinden müssen, nur diese Input verwenden, die sie in eine im Fluge kombiniert.

import java.io.IOException;  
import java.io.InputStream;  

import android.content.res.AssetManager;  

public class SplitFileInputStream extends InputStream {  

  private String baseName;  
  private String ext;  
  private AssetManager am;  
  private int numberOfChunks;  
  private int currentChunk = 1;  
  private InputStream currentIs = null;  

  public SplitFileInputStream(String baseName, String ext, int numberOfChunks, AssetManager am) throws IOException {  
    this.baseName = baseName;  
    this.am = am;  
    this.numberOfChunks = numberOfChunks;  
    this.ext = ext;  
    currentIs = am.open(baseName + currentChunk + ext, AssetManager.ACCESS_STREAMING);  
  }  

  @Override  
  public int read() throws IOException {  
    int read = currentIs.read();  
    if (read == -1 && currentChunk < numberOfChunks) {  
      currentIs.close();  
      currentIs = am.open(baseName + ++currentChunk + ext, AssetManager.ACCESS_STREAMING);  
      return read();  
    }  
    return read;  
  }  

  @Override  
  public int available() throws IOException {  
    return currentIs.available();  
  }  

  @Override  
  public void close() throws IOException {  
    currentIs.close();  
  }  

  @Override  
  public void mark(int readlimit) {  
    throw new UnsupportedOperationException();  
  }  

  @Override  
  public boolean markSupported() {  
    return false;  
  }  

  @Override  
  public int read(byte[] b, int offset, int length) throws IOException {  
    int read = currentIs.read(b, offset, length);  
    if (read < length && currentChunk < numberOfChunks) {  
      currentIs.close();  
      currentIs = am.open(baseName + ++currentChunk + ext, AssetManager.ACCESS_STREAMING);  
      read += read(b, offset + read, length - read);  
    }  
    return read;  
  }  

  @Override  
  public int read(byte[] b) throws IOException {  
    return read(b, 0, b.length);  
  }  

  @Override  
  public synchronized void reset() throws IOException {  
    if (currentChunk == 1) {  
      currentIs.reset();  
    } else {  
      currentIs.close();  
      currentIs = am.open(baseName + currentChunk + ext, AssetManager.ACCESS_STREAMING);  
      currentChunk = 1;  
    }  
  }  

  @Override  
  public long skip(long n) throws IOException {  
    long skipped = currentIs.skip(n);  
    if (skipped < n && currentChunk < numberOfChunks) {  
      currentIs.close();  
      currentIs = am.open(baseName + ++currentChunk + ext, AssetManager.ACCESS_STREAMING);  
      skipped += skip(n - skipped);  
    }  
    return skipped;  
  }  
}

Verbrauch:
    ObjectInputStream ois = new ObjectInputStream(new SplitFileInputStream("mytempfile", ".dat", 4, getAssets()));

Ändern Sie die Dateierweiterung .mp3

Ich weiß, das ist eine alte Frage, aber ich dachte an eine gute Lösung. Warum speichern Sie die Datei nicht bereits vorge Reißverschluss in den Asset-Ordnern. Dann, da es bereits eine ZIP-Datei und somit komprimiert es nicht erneut komprimiert werden müssen. Also, wenn Sie die Datei komprimiert werden, um eine Verringerung der Größe Ihrer apk wollte, aber Sie wollen nicht mit Aufspaltung Dateien umgehen Ich denke, das ist einfacher.

Wenn Sie die Datei aus dem Gerät lesen müssen wickeln nur den Eingabestrom in einem ZipInputStream http://developer.android.com/reference/java/util/zip /ZipInputStream.html

ich eine andere Lösung gefunden, vielleicht sind Sie daran interessiert.

In der Wurzel Ihrer Quellen, wo Sie die build.xml-Datei haben, können Sie das -package-resources Ziel in der custom_rules.xml Datei überschreiben, die für das Hinzufügen / Modifizieren Ziele in ant verwendet wird, ohne etwas in dem Standard-Android-App-Build-System zu brechen.

Erstellen Sie einfach eine Datei mit folgendem Inhalt:

<?xml version="1.0" encoding="UTF-8"?>
<project name="yourAppHere" default="help">

    <target name="-package-resources" depends="-crunch">
        <!-- only package resources if *not* a library project -->
        <do-only-if-not-library elseText="Library project: do not package resources..." >
            <aapt executable="${aapt}"
                    command="package"
                    versioncode="${version.code}"
                    versionname="${version.name}"
                    debug="${build.is.packaging.debug}"
                    manifest="${out.manifest.abs.file}"
                    assets="${asset.absolute.dir}"
                    androidjar="${project.target.android.jar}"
                    apkfolder="${out.absolute.dir}"
                    nocrunch="${build.packaging.nocrunch}"
                    resourcefilename="${resource.package.file.name}"
                    resourcefilter="${aapt.resource.filter}"
                    libraryResFolderPathRefid="project.library.res.folder.path"
                    libraryPackagesRefid="project.library.packages"
                    libraryRFileRefid="project.library.bin.r.file.path"
                    previousBuildType="${build.last.target}"
                    buildType="${build.target}"
                    ignoreAssets="${aapt.ignore.assets}">
                <res path="${out.res.absolute.dir}" />
                <res path="${resource.absolute.dir}" />
                <nocompress /> <!-- forces no compression on any files in assets or res/raw -->
                <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw -->
            </aapt>
        </do-only-if-not-library>
    </target>
</project>

Add-Dateierweiterung ist mp3.I Verwendung mydb.mp3in Vermögenswerte Ordner und kopieren .this laufen ohne error.show es zu überprüfen.

Mit GZIP würde eine andere Methode. nur müssen Sie wickeln Input innerhalb von GZIPInputStream .
Früher habe ich dies für eine Datenbank, die Größe etwa 3,0 MB und Ausgabe komprimieren Datei über 600KB war.

  • Für DB Kopieren in Tannen laufen, ich gzipped meine Quelle .db-Datei GZIP Werkzeug .
  • umbenannt es dann zu .jpg um mehr Kompression zu vermeiden (Diese Prozesse vor der Kompilierung APK-Datei durchgeführt).
  • Dann zum Lesen komprimierte GZIP-Datei aus assetss

und kopiert es:

private void copydatabase() throws IOException {
        // Open your local db as the input stream
        InputStream myinput = mContext.getAssets().open(DB_NAME_ASSET);
        BufferedInputStream buffStream = new BufferedInputStream(myinput);
        GZIPInputStream zis = new GZIPInputStream(buffStream);

        // Path to the just created empty db
        String outfilename = DB_PATH + DB_NAME;

        // Open the empty db as the output stream
        OutputStream myoutput = new FileOutputStream(outfilename);


        // transfer byte to inputfile to outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = zis.read(buffer)) > 0) {
            myoutput.write(buffer, 0, length);
        }

        // Close the streams
        myoutput.flush();
        myoutput.close();
        zis.close();
        buffStream.close();
        myinput.close();
    }

Datenbank auf mehr Teil mit einem Programm, zB "Win Hex", können Sie herunterladen von Link

und weiter Dateien laden größer als 1M von Vermögenswerten Ordner

Anstelle von Vermögenswerten Ordnern, ich habe meine großen Dateien im Raw-Ordnern. Für mich geht das.

Ich benutze NetBeans das Paket zu erstellen, und ich fand nicht, wie die Einstellungen von AAPT zu ändern. Ich habe die png nicht ausprobiert, aber die mp3 komprimiert werden. Ich kann das Paket zusammenstellen und dann die Assets eingeben Ordner mit dem Parameter -0? was wäre die richtige Verwendung des Befehls sein?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top