'সম্পদ' ফোল্ডার থেকে এসডিকার্ডে কীভাবে ফাইলগুলি অনুলিপি করবেন?


251

assetsফোল্ডারে আমার কয়েকটি ফাইল রয়েছে । আমি তাদের সবগুলি / sdcard / ফোল্ডার বলার ফোল্ডারে অনুলিপি করতে হবে। আমি এটি একটি থ্রেডের মধ্যে থেকে করতে চাই। আমি এটা কিভাবে করব?


আপনি এই খুঁজছেন stackoverflow.com/questions/4447477/...
DropAndTrap

2
: (! মহান) আগে আপনি কপি / নীচের সমাধানগুলি এক পেস্ট বিবেচনা কোডের এক লাইনে এটা করতে এই লাইব্রেরি ব্যবহার stackoverflow.com/a/41970539/9648
JohnnyLambada

উত্তর:


346

অন্য কারও যদি একই সমস্যা হয় তবে আমি এটি এটি করেছিলাম

private void copyAssets() {
    AssetManager assetManager = getAssets();
    String[] files = null;
    try {
        files = assetManager.list("");
    } catch (IOException e) {
        Log.e("tag", "Failed to get asset file list.", e);
    }
    if (files != null) for (String filename : files) {
        InputStream in = null;
        OutputStream out = null;
        try {
          in = assetManager.open(filename);
          File outFile = new File(getExternalFilesDir(null), filename);
          out = new FileOutputStream(outFile);
          copyFile(in, out);
        } catch(IOException e) {
            Log.e("tag", "Failed to copy asset file: " + filename, e);
        }     
        finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
        }  
    }
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while((read = in.read(buffer)) != -1){
      out.write(buffer, 0, read);
    }
}

তথ্যসূত্র: জাভা ব্যবহার করে ফাইল সরান


28
এসডকার্ডে ফাইলগুলি লিখতে আপনাকে ম্যানিফেস্টে অনুমতি দিতে হবে যেমন <ব্যবহারের অনুমতি অ্যান্ড্রয়েড: নাম = "android.permission.WRITE_EXTERNAL_STORAGE" />
আয়রনব্লসম


2
আমি কি ব্যবহার করব: 16 * 1024 (16 কেবি) আমি মেমরির ব্যবহার এবং পারফরম্যান্সের মধ্যে একটি ভাল ভারসাম্য হিসাবে 16 কে বা 32 কে পছন্দ করি।
নাম ভু

3
@ রিসিওবাতি এই রানটাইম ত্রুটিটি পেয়েছেFailed to copy asset file: myfile.txt java.io.FileNotFoundException: myfile.txt at android.content.res.AssetManager.openAsset(Native Method)
জুলাই

7
আমার জন্য এই কোডটি কেবল তখনই যুক্ত করি যদি আমি এটি যুক্ত করি: in = assetManager.open("images-wall/"+filename);যেখানে "চিত্র-প্রাচীর" সম্পদের অভ্যন্তরে আমার ফোল্ডার
Ultimo_m

62

আপনার সমাধানের ভিত্তিতে, সাবফোল্ডারগুলিকে অনুমতি দেওয়ার জন্য আমি আমার নিজস্ব কিছু করেছি। কেউ এটি সহায়ক হতে পারে:

...

copyFileOrDir("myrootdir");

...

private void copyFileOrDir(String path) {
    AssetManager assetManager = this.getAssets();
    String assets[] = null;
    try {
        assets = assetManager.list(path);
        if (assets.length == 0) {
            copyFile(path);
        } else {
            String fullPath = "/data/data/" + this.getPackageName() + "/" + path;
            File dir = new File(fullPath);
            if (!dir.exists())
                dir.mkdir();
            for (int i = 0; i < assets.length; ++i) {
                copyFileOrDir(path + "/" + assets[i]);
            }
        }
    } catch (IOException ex) {
        Log.e("tag", "I/O Exception", ex);
    }
}

private void copyFile(String filename) {
    AssetManager assetManager = this.getAssets();

    InputStream in = null;
    OutputStream out = null;
    try {
        in = assetManager.open(filename);
        String newFileName = "/data/data/" + this.getPackageName() + "/" + filename;
        out = new FileOutputStream(newFileName);

        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
    } catch (Exception e) {
        Log.e("tag", e.getMessage());
    }

}

1
assetManager.list(path)ডিভাইসে ধীর গতি হতে পারে, সম্পদের পাথের তালিকা তৈরি করতে আগে এই স্নিপেটটি assetsদির থেকে ব্যবহার করা যেতে পারে :find . -name "*" -type f -exec ls -l {} \; | awk '{print substr($9,3)}' >> assets.list
আলেকাসকো

3
চমৎকার সমাধান! একমাত্র প্রয়োজনীয় ফিক্সটি হ'ল কপিফিলঅর্ডার () এর শুরুতে নেতৃস্থানীয় বিভাজকগুলি ছাঁটাই: পথ = পথ.আরম্ভের সাথে ("/")? path.substring (1): পথ;
ক্রস_ম


2
প্রতিস্থাপন "/ ডেটা / ডেটা /," + this.getPackageName () this.getFilesDir () সঙ্গে getAbsolutePath ()।
ibrahimyilmaz

1
... এবং finallyব্লক স্ট্রিমগুলি বন্ধ করুন))
মিকাজাজ

48

কিছু ত্রুটির কারণে উপরের সমাধানটি কার্যকর হয়নি:

  • ডিরেক্টরি তৈরির কাজ হয়নি
  • অ্যান্ড্রয়েড দ্বারা ফিরে আসা সম্পদে তিনটি ফোল্ডারও রয়েছে: চিত্র, শব্দ এবং ওয়েবকিট
  • বড় ফাইলগুলির সাথে কাজ করার জন্য যুক্ত করা উপায়: আপনার প্রকল্পের সম্পদ ফোল্ডারে ফাইলটিতে এক্সটেনশন। এমপি 3 যুক্ত করুন এবং অনুলিপি করার সময় লক্ষ্য ফাইলটি এমপি 3 এক্সটেনশন ছাড়াই থাকবে

এখানে কোডটি রয়েছে (আমি লগের বিবৃতি ছেড়ে দিয়েছি তবে আপনি সেগুলি এখনই ফেলে দিতে পারেন):

final static String TARGET_BASE_PATH = "/sdcard/appname/voices/";

private void copyFilesToSdCard() {
    copyFileOrDir(""); // copy all files in assets folder in my project
}

private void copyFileOrDir(String path) {
    AssetManager assetManager = this.getAssets();
    String assets[] = null;
    try {
        Log.i("tag", "copyFileOrDir() "+path);
        assets = assetManager.list(path);
        if (assets.length == 0) {
            copyFile(path);
        } else {
            String fullPath =  TARGET_BASE_PATH + path;
            Log.i("tag", "path="+fullPath);
            File dir = new File(fullPath);
            if (!dir.exists() && !path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit"))
                if (!dir.mkdirs())
                    Log.i("tag", "could not create dir "+fullPath);
            for (int i = 0; i < assets.length; ++i) {
                String p;
                if (path.equals(""))
                    p = "";
                else 
                    p = path + "/";

                if (!path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit"))
                    copyFileOrDir( p + assets[i]);
            }
        }
    } catch (IOException ex) {
        Log.e("tag", "I/O Exception", ex);
    }
}

private void copyFile(String filename) {
    AssetManager assetManager = this.getAssets();

    InputStream in = null;
    OutputStream out = null;
    String newFileName = null;
    try {
        Log.i("tag", "copyFile() "+filename);
        in = assetManager.open(filename);
        if (filename.endsWith(".jpg")) // extension was added to avoid compression on APK file
            newFileName = TARGET_BASE_PATH + filename.substring(0, filename.length()-4);
        else
            newFileName = TARGET_BASE_PATH + filename;
        out = new FileOutputStream(newFileName);

        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
    } catch (Exception e) {
        Log.e("tag", "Exception in copyFile() of "+newFileName);
        Log.e("tag", "Exception in copyFile() "+e.toString());
    }

}

সম্পাদনা: একটি ভুল জায়গায় সংশোধন করা হয়েছে ";" এটি একটি পদ্ধতিগত "তীর তৈরি করতে পারে না" ত্রুটি ছুড়েছিল।


4
এটি অবশ্যই সমাধান হয়ে উঠবে!
ম্যাসিমো ভারিলো

1
দ্রষ্টব্য: লগ.আই ("ট্যাগ", "দির তৈরি করতে পারেনি" + পুরোপথ); সর্বদা হিসাবে ঘটে; যদি ভুল জায়গায় স্থানান্তরিত হয়।
রাউন্ডস্প্যারো হিলিটেক্স

দুর্দান্ত উপায়! অনেক ধন্যবাদ! তবে আপনি কেন জেপিজি ফাইল চেক করেন?
ফুং

32

আমি জানি এটির উত্তর দেওয়া হয়েছে তবে এসডকার্ডের কোনও ফাইলের জন্য সম্পদ ডিরেক্টরি থেকে অনুলিপি করার আমার কাছে আরও কিছু মার্জিত উপায় আছে। এটিতে "জন্য" লুপের প্রয়োজন নেই বরং কাজটি করার জন্য ফাইল স্ট্রিম এবং চ্যানেলগুলি ব্যবহার করে।

(দ্রষ্টব্য) যদি কোনও ধরণের সংকোচিত ফাইল, APK, পিডিএফ, ... ব্যবহার করে থাকেন তবে আপনি সম্পদ সন্নিবেশ করার আগে ফাইল এক্সটেনশনটির নাম পরিবর্তন করতে এবং তারপরে আপনি এসডিকার্ডে অনুলিপি করার পরে পুনরায় নামকরণ করতে পারেন)

AssetManager am = context.getAssets();
AssetFileDescriptor afd = null;
try {
    afd = am.openFd( "MyFile.dat");

    // Create new file to copy into.
    File file = new File(Environment.getExternalStorageDirectory() + java.io.File.separator + "NewFile.dat");
    file.createNewFile();

    copyFdToFile(afd.getFileDescriptor(), file);

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

এর মাধ্যমে লুপ না করে কোনও ফাইল অনুলিপি করার উপায়।

public static void copyFdToFile(FileDescriptor 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();
    }
}

অন্যান্য সমাধানগুলির তুলনায় এটি পছন্দ হয়েছে খনিতে সামান্য পরিবর্তন যা হারিয়ে যাওয়া ফাইল ফোল্ডারগুলি অন্তর্ভুক্ত করে। চিয়ার্স!
ক্রিস। জেনকিন্স

3
এটি আমার জন্য ফাইল বিবরণীর কাজ করতে পারে না This file can not be opened as a file descriptor; it is probably compressed- এটি একটি পিডিএফ ফাইল। কিভাবে এটি ঠিক করতে জানেন?
গা

1
এটি ধরে নিয়েছে যে ইনচ্যানেল.সাইজ () ফাইলের আকারের আকার দেয়। এটি এরকম কোনও গ্যারান্টি দেয় না । আমি 2 টি ফাইলের জন্য 2.5 টি এমআইবি পাচ্ছি যা প্রতি 450 কিবি হয়।
AI0867

1
আমি সবেমাত্র খুঁজে পেয়েছি যে AssetFileDescriptor.getLength () সঠিক ফাইলাইজ ফিরিয়ে দেবে।
AI0867

1
উপরের পাশাপাশি, সম্পদটি ফাইল বর্ণনাকারীতে 0 অবস্থান থেকে শুরু নাও হতে পারে। AssetFileDescriptor.getStartOffset () প্রারম্ভিক অফসেটটি ফিরিয়ে দেবে।
AI0867

5

এটি চেষ্টা করুন এটি অনেক সহজ, এটি আপনাকে সাহায্য করবে:

// Open your local db as the input stream
    InputStream myInput = _context.getAssets().open(YOUR FILE NAME);

    // Path to the just created empty db
    String outFileName =SDCARD PATH + YOUR FILE NAME;

    // Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    // transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }
    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();

5

এটি কোটলিনে সংক্ষিপ্ত পথ হবে।

    fun AssetManager.copyRecursively(assetPath: String, targetFile: File) {
        val list = list(assetPath)
        if (list.isEmpty()) { // assetPath is file
            open(assetPath).use { input ->
                FileOutputStream(targetFile.absolutePath).use { output ->
                    input.copyTo(output)
                    output.flush()
                }
            }

        } else { // assetPath is folder
            targetFile.delete()
            targetFile.mkdir()

            list.forEach {
                copyRecursively("$assetPath/$it", File(targetFile, it))
            }
        }
    }

তালিকা (সম্পদপথ) ?. আসুন আসলে {...} দিন। এটা নলাবল।
গ্যাবার

4

এখানে বর্তমান অ্যান্ড্রয়েড ডিভাইসগুলির জন্য একটি ক্লিন আপ সংস্করণ রয়েছে, কার্যকরী পদ্ধতি ডিজাইনের যাতে আপনি এটি কোনও এসেটস হেলপার শ্রেণিতে অনুলিপি করতে পারেন যেমন;)

/**
 * 
 * Info: prior to Android 2.3, any compressed asset file with an
 * uncompressed size of over 1 MB cannot be read from the APK. So this
 * should only be used if the device has android 2.3 or later running!
 * 
 * @param c
 * @param targetFolder
 *            e.g. {@link Environment#getExternalStorageDirectory()}
 * @throws Exception
 */
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public static boolean copyAssets(AssetManager assetManager,
        File targetFolder) throws Exception {
    Log.i(LOG_TAG, "Copying files from assets to folder " + targetFolder);
    return copyAssets(assetManager, "", targetFolder);
}

/**
 * The files will be copied at the location targetFolder+path so if you
 * enter path="abc" and targetfolder="sdcard" the files will be located in
 * "sdcard/abc"
 * 
 * @param assetManager
 * @param path
 * @param targetFolder
 * @return
 * @throws Exception
 */
public static boolean copyAssets(AssetManager assetManager, String path,
        File targetFolder) throws Exception {
    Log.i(LOG_TAG, "Copying " + path + " to " + targetFolder);
    String sources[] = assetManager.list(path);
    if (sources.length == 0) { // its not a folder, so its a file:
        copyAssetFileToFolder(assetManager, path, targetFolder);
    } else { // its a folder:
        if (path.startsWith("images") || path.startsWith("sounds")
                || path.startsWith("webkit")) {
            Log.i(LOG_TAG, "  > Skipping " + path);
            return false;
        }
        File targetDir = new File(targetFolder, path);
        targetDir.mkdirs();
        for (String source : sources) {
            String fullSourcePath = path.equals("") ? source : (path
                    + File.separator + source);
            copyAssets(assetManager, fullSourcePath, targetFolder);
        }
    }
    return true;
}

private static void copyAssetFileToFolder(AssetManager assetManager,
        String fullAssetPath, File targetBasePath) throws IOException {
    InputStream in = assetManager.open(fullAssetPath);
    OutputStream out = new FileOutputStream(new File(targetBasePath,
            fullAssetPath));
    byte[] buffer = new byte[16 * 1024];
    int read;
    while ((read = in.read(buffer)) != -1) {
        out.write(buffer, 0, read);
    }
    in.close();
    out.flush();
    out.close();
}

4

@ ড্যানিএ দ্বারা এই এসও উত্তরটি সংশোধন করেছেন

private void copyAssets(String path, String outPath) {
    AssetManager assetManager = this.getAssets();
    String assets[];
    try {
        assets = assetManager.list(path);
        if (assets.length == 0) {
            copyFile(path, outPath);
        } else {
            String fullPath = outPath + "/" + path;
            File dir = new File(fullPath);
            if (!dir.exists())
                if (!dir.mkdir()) Log.e(TAG, "No create external directory: " + dir );
            for (String asset : assets) {
                copyAssets(path + "/" + asset, outPath);
            }
        }
    } catch (IOException ex) {
        Log.e(TAG, "I/O Exception", ex);
    }
}

private void copyFile(String filename, String outPath) {
    AssetManager assetManager = this.getAssets();

    InputStream in;
    OutputStream out;
    try {
        in = assetManager.open(filename);
        String newFileName = outPath + "/" + filename;
        out = new FileOutputStream(newFileName);

        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        out.flush();
        out.close();
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
    }

}

উদ্যতি

মধ্যে src/main/assets নাম দিয়ে অ্যাড ফোল্ডারেরfold

ব্যবহার

File outDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString());
copyAssets("fold",outDir.toString());

বাহ্যিক ডিরেক্টরিতে ভাঁজ সম্পদের মধ্যে থাকা সমস্ত ফাইল এবং ডিরেক্টরিগুলি সন্ধান করুন


3

সম্পদ থেকে সমস্ত ফাইল এবং ডিরেক্টরিগুলি আপনার ফোল্ডারে অনুলিপি করুন!

আরও ভাল অ্যাপাচি কমন্স অনুলিপি করার জন্য io

public void doCopyAssets() throws IOException {
    File externalFilesDir = context.getExternalFilesDir(null);

    doCopy("", externalFilesDir.getPath());

}

// এটি কপির জন্য মূল পদ্ধতি

private void doCopy(String dirName, String outPath) throws IOException {

    String[] srcFiles = assets.list(dirName);//for directory
    for (String srcFileName : srcFiles) {
        String outFileName = outPath + File.separator + srcFileName;
        String inFileName = dirName + File.separator + srcFileName;
        if (dirName.equals("")) {// for first time
            inFileName = srcFileName;
        }
        try {
            InputStream inputStream = assets.open(inFileName);
            copyAndClose(inputStream, new FileOutputStream(outFileName));
        } catch (IOException e) {//if directory fails exception
            new File(outFileName).mkdir();
            doCopy(inFileName, outFileName);
        }

    }
}

public static void closeQuietly(AutoCloseable autoCloseable) {
    try {
        if(autoCloseable != null) {
            autoCloseable.close();
        }
    } catch(IOException ioe) {
        //skip
    }
}

public static void copyAndClose(InputStream input, OutputStream output) throws IOException {
    copy(input, output);
    closeQuietly(input);
    closeQuietly(output);
}

public static void copy(InputStream input, OutputStream output) throws IOException {
    byte[] buffer = new byte[1024];
    int n = 0;
    while(-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
    }
}

2

ইওরাম কোহেন উত্তরের উপর ভিত্তি করে, এখানে এমন একটি সংস্করণ রয়েছে যা অ স্ট্যাটিক টার্গেট ডিরেক্টরি সমর্থন করে।

সঙ্গে Invoque copyFileOrDir(getDataDir(), "")লিখতে অভ্যন্তরীণ অ্যাপ্লিকেশন সঞ্চয়স্থানের ফোল্ডারের / ডাটা / ডেটা / pkg_name /

  • সাবফোল্ডার সমর্থন করে।
  • কাস্টম এবং অ স্থিত লক্ষ্য ডিরেক্টরি সমর্থন করে
  • "চিত্র" ইত্যাদি নকল সম্পদ ফোল্ডারগুলির মতো অনুলিপি করা থেকে বিরত থাকে

    private void copyFileOrDir(String TARGET_BASE_PATH, String path) {
    AssetManager assetManager = this.getAssets();
    String assets[] = null;
    try {
        Log.i("tag", "copyFileOrDir() "+path);
        assets = assetManager.list(path);
        if (assets.length == 0) {
            copyFile(TARGET_BASE_PATH, path);
        } else {
            String fullPath =  TARGET_BASE_PATH + "/" + path;
            Log.i("tag", "path="+fullPath);
            File dir = new File(fullPath);
            if (!dir.exists() && !path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit"))
                if (!dir.mkdirs())
                    Log.i("tag", "could not create dir "+fullPath);
            for (int i = 0; i < assets.length; ++i) {
                String p;
                if (path.equals(""))
                    p = "";
                else 
                    p = path + "/";
    
                if (!path.startsWith("images") && !path.startsWith("sounds") && !path.startsWith("webkit"))
                    copyFileOrDir(TARGET_BASE_PATH, p + assets[i]);
            }
        }
    } catch (IOException ex) {
        Log.e("tag", "I/O Exception", ex);
    }
    }
    
    private void copyFile(String TARGET_BASE_PATH, String filename) {
    AssetManager assetManager = this.getAssets();
    
    InputStream in = null;
    OutputStream out = null;
    String newFileName = null;
    try {
        Log.i("tag", "copyFile() "+filename);
        in = assetManager.open(filename);
        if (filename.endsWith(".jpg")) // extension was added to avoid compression on APK file
            newFileName = TARGET_BASE_PATH + "/" + filename.substring(0, filename.length()-4);
        else
            newFileName = TARGET_BASE_PATH + "/" + filename;
        out = new FileOutputStream(newFileName);
    
        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
    } catch (Exception e) {
        Log.e("tag", "Exception in copyFile() of "+newFileName);
        Log.e("tag", "Exception in copyFile() "+e.toString());
    }
    
    }

2

এই প্রশ্নের উত্তরে কয়েকটি ধারণার ব্যবহার করে, আমি AssetCopierঅনুলিপিটিকে /assets/সহজ করার জন্য ডাকা একটি ক্লাস লিখেছিলাম । এটা তোলে উপলব্ধ GitHub এবং অ্যাক্সেস করা যেতে পারে jitpack.io :

new AssetCopier(MainActivity.this)
        .withFileScanning()
        .copy("tocopy", destDir);

আরও তথ্যের জন্য https://github.com/flipગ્રામ/ android- assetcopier দেখুন ।


2

এটি করার জন্য দুটি উপায় রয়েছে।

প্রথমত, আপনি অ্যাসেটম্যানেজআরওপেন এবং রোহিত নন্দকুমার বর্ণিত হিসাবে এবং ইনপুটস্ট্রিমে পুনরাবৃত্তি করতে পারেন ।

দ্বিতীয়ত, আপনি AssetManager.openFd ব্যবহার করতে পারেন , যা আপনাকে একটি ফাইলচ্যানেল ব্যবহার করতে দেয় (যার মধ্যে [ট্রান্সফারটো) রয়েছে ( https://developer.android.com/references/java/nio/channels/FileChannel.html#transferTo(long , দীর্ঘ, java.nio.channels.WritableByteChannel)) এবং [ট্রান্সফারফ্রমে] ( https://developer.android.com/references/java/nio/channels/FileChannel.html#transferFrom(java.nio.channels.RedadableByteChannel , দীর্ঘ, দীর্ঘ)) পদ্ধতিগুলি), যাতে আপনাকে নিজের ইনপুট স্ট্রিমটি লুপ করতে হবে না।

আমি এখানে ওপেনফিড পদ্ধতিটি বর্ণনা করব।

সঙ্কোচন

প্রথমে আপনাকে নিশ্চিত করতে হবে যে ফাইলটি সঙ্কুচিত। প্যাকেজিং সিস্টেমটি এমন কোনও এক্সটেনশন দিয়ে কোনও ফাইল সংকোচিত করতে বেছে নিতে পারে যা নো কমপ্রেস হিসাবে চিহ্নিত নয় এবং সংকোচিত ফাইলগুলিকে মেমরি ম্যাপ করা যায় না, সেই ক্ষেত্রে আপনাকে অ্যাসেটম্যানেজআরওপেনের উপর নির্ভর করতে হবে ।

আপনার ফাইলটিকে সংকুচিত হওয়া থেকে বিরত রাখতে আপনি একটি '.mp3' এক্সটেনশন যুক্ত করতে পারেন তবে সঠিক সমাধানটি হ'ল আপনার অ্যাপ / বিল্ড.gradle ফাইলটি সংশোধন করে নিম্নলিখিত লাইনগুলি যুক্ত করুন (পিডিএফ ফাইলের সংক্ষেপণ অক্ষম করতে)

aaptOptions {
    noCompress 'pdf'
}

ফাইল প্যাকিং

নোট করুন যে প্যাকেজকারী এখনও একাধিক ফাইল প্যাক করতে পারে, তাই আপনি অ্যাসেটম্যানেজার আপনাকে যে পুরো ফাইলটি দিতে পারেন তা কেবল পড়তে পারবেন না । আপনার কোন অংশগুলির প্রয়োজন তা আপনার অ্যাসেটফিলডিস্কিটারকে জিজ্ঞাসা করতে হবে।

প্যাক করা ফাইলটির সঠিক অংশ সন্ধান করা

একবার আপনার ফাইলটি সঙ্কুচিতভাবে সংরক্ষণ করা হয়েছে তা নিশ্চিত করার পরে, আপনি একটি অ্যাসেটফায়ালডিসিপ্টার অর্জন করতে AssetManager.openFd পদ্ধতিটি ব্যবহার করতে পারেন , যা একটি ফাইলইনপুটস্ট্রিম প্রাপ্ত করতে ব্যবহার করা যেতে পারে ( AssetManager.open এর বিপরীতে , যা একটি ইনপুট স্ট্রিম প্রদান করে ) এতে একটি ফাইলচ্যানেল রয়েছে । এটিতে প্রারম্ভিক অফসেট (getStartOffset) এবং আকার (getLength) রয়েছে যা আপনাকে ফাইলের সঠিক অংশটি অর্জন করতে হবে।

বাস্তবায়ন

একটি বাস্তবায়ন নীচে দেওয়া হল:

private void copyFileFromAssets(String in_filename, File out_file){
    Log.d("copyFileFromAssets", "Copying file '"+in_filename+"' to '"+out_file.toString()+"'");
    AssetManager assetManager = getApplicationContext().getAssets();
    FileChannel in_chan = null, out_chan = null;
    try {
        AssetFileDescriptor in_afd = assetManager.openFd(in_filename);
        FileInputStream in_stream = in_afd.createInputStream();
        in_chan = in_stream.getChannel();
        Log.d("copyFileFromAssets", "Asset space in file: start = "+in_afd.getStartOffset()+", length = "+in_afd.getLength());
        FileOutputStream out_stream = new FileOutputStream(out_file);
        out_chan = out_stream.getChannel();
        in_chan.transferTo(in_afd.getStartOffset(), in_afd.getLength(), out_chan);
    } catch (IOException ioe){
        Log.w("copyFileFromAssets", "Failed to copy file '"+in_filename+"' to external storage:"+ioe.toString());
    } finally {
        try {
            if (in_chan != null) {
                in_chan.close();
            }
            if (out_chan != null) {
                out_chan.close();
            }
        } catch (IOException ioe){}
    }
}

এই উত্তরটি জেপিএমের উত্তরের ভিত্তিতে ।


1
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        copyReadAssets();
    }


    private void copyReadAssets()
    {
        AssetManager assetManager = getAssets();

        InputStream in = null;
        OutputStream out = null;

        String strDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+ File.separator + "Pdfs";
        File fileDir = new File(strDir);
        fileDir.mkdirs();   // crear la ruta si no existe
        File file = new File(fileDir, "example2.pdf");



        try
        {

            in = assetManager.open("example.pdf");  //leer el archivo de assets
            out = new BufferedOutputStream(new FileOutputStream(file)); //crear el archivo


            copyFile(in, out);
            in.close();
            in = null;
            out.flush();
            out.close();
            out = null;
        } catch (Exception e)
        {
            Log.e("tag", e.getMessage());
        }

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse("file://" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + "Pdfs" + "/example2.pdf"), "application/pdf");
        startActivity(intent);
    }

    private void copyFile(InputStream in, OutputStream out) throws IOException
    {
        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1)
        {
            out.write(buffer, 0, read);
        }
    }
}

কোডের অংশগুলি এর মতো পরিবর্তন করুন:

out = new BufferedOutputStream(new FileOutputStream(file));

পূর্বের উদাহরণটি পিডিএফএসের জন্য, উদাহরণস্বরূপ .txt

FileOutputStream fos = new FileOutputStream(file);

1

অ্যাসেটম্যানেজার ব্যবহার করুন , এটি সম্পদের ফাইলগুলি পড়তে দেয়। তারপরে ফাইলগুলিকে এসডকার্ডে লিখতে নিয়মিত জাভা আইও ব্যবহার করুন।

গুগল আপনার বন্ধু, উদাহরণের জন্য অনুসন্ধান করুন।


1

হাই গাইস আই ডিড কিছু এই জাতীয়। এন-তম গভীরতার কপি ফোল্ডার এবং ফাইলগুলি অনুলিপি করতে। যা আপনাকে অ্যান্ড্রয়েড অ্যাসেটম্যানেজার থেকে অনুলিপি করতে সমস্ত ডিরেক্টরি কাঠামো অনুলিপি করার অনুমতি দেয় :)

    private void manageAssetFolderToSDcard()
    {

        try
        {
            String arg_assetDir = getApplicationContext().getPackageName();
            String arg_destinationDir = FRConstants.ANDROID_DATA + arg_assetDir;
            File FolderInCache = new File(arg_destinationDir);
            if (!FolderInCache.exists())
            {
                copyDirorfileFromAssetManager(arg_assetDir, arg_destinationDir);
            }
        } catch (IOException e1)
        {

            e1.printStackTrace();
        }

    }


    public String copyDirorfileFromAssetManager(String arg_assetDir, String arg_destinationDir) throws IOException
    {
        File sd_path = Environment.getExternalStorageDirectory(); 
        String dest_dir_path = sd_path + addLeadingSlash(arg_destinationDir);
        File dest_dir = new File(dest_dir_path);

        createDir(dest_dir);

        AssetManager asset_manager = getApplicationContext().getAssets();
        String[] files = asset_manager.list(arg_assetDir);

        for (int i = 0; i < files.length; i++)
        {

            String abs_asset_file_path = addTrailingSlash(arg_assetDir) + files[i];
            String sub_files[] = asset_manager.list(abs_asset_file_path);

            if (sub_files.length == 0)
            {
                // It is a file
                String dest_file_path = addTrailingSlash(dest_dir_path) + files[i];
                copyAssetFile(abs_asset_file_path, dest_file_path);
            } else
            {
                // It is a sub directory
                copyDirorfileFromAssetManager(abs_asset_file_path, addTrailingSlash(arg_destinationDir) + files[i]);
            }
        }

        return dest_dir_path;
    }


    public void copyAssetFile(String assetFilePath, String destinationFilePath) throws IOException
    {
        InputStream in = getApplicationContext().getAssets().open(assetFilePath);
        OutputStream out = new FileOutputStream(destinationFilePath);

        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0)
            out.write(buf, 0, len);
        in.close();
        out.close();
    }

    public String addTrailingSlash(String path)
    {
        if (path.charAt(path.length() - 1) != '/')
        {
            path += "/";
        }
        return path;
    }

    public String addLeadingSlash(String path)
    {
        if (path.charAt(0) != '/')
        {
            path = "/" + path;
        }
        return path;
    }

    public void createDir(File dir) throws IOException
    {
        if (dir.exists())
        {
            if (!dir.isDirectory())
            {
                throw new IOException("Can't create directory, a file is in the way");
            }
        } else
        {
            dir.mkdirs();
            if (!dir.isDirectory())
            {
                throw new IOException("Unable to create directory");
            }
        }
    }

শেষ পর্যন্ত একটি অ্যাসিঙ্কটাস্ক তৈরি করুন:

    private class ManageAssetFolders extends AsyncTask<Void, Void, Void>
    {

        @Override
        protected Void doInBackground(Void... arg0)
        {
            manageAssetFolderToSDcard();
            return null;
        }

    }

আপনার ক্রিয়াকলাপ থেকে এটি কল করুন:

    new ManageAssetFolders().execute();

1

পুনরাবৃত্তভাবে একটি ফোল্ডার অনুলিপি করতে এবং কাস্টম গন্তব্যকে সামঞ্জস্য করতে উপরের উত্তরের সামান্য পরিবর্তন mod

public void copyFileOrDir(String path, String destinationDir) {
    AssetManager assetManager = this.getAssets();
    String assets[] = null;
    try {
        assets = assetManager.list(path);
        if (assets.length == 0) {
            copyFile(path,destinationDir);
        } else {
            String fullPath = destinationDir + "/" + path;
            File dir = new File(fullPath);
            if (!dir.exists())
                dir.mkdir();
            for (int i = 0; i < assets.length; ++i) {
                copyFileOrDir(path + "/" + assets[i], destinationDir + path + "/" + assets[i]);
            }
        }
    } catch (IOException ex) {
        Log.e("tag", "I/O Exception", ex);
    }
}

private void copyFile(String filename, String destinationDir) {
    AssetManager assetManager = this.getAssets();
    String newFileName = destinationDir + "/" + filename;

    InputStream in = null;
    OutputStream out = null;
    try {
        in = assetManager.open(filename);
        out = new FileOutputStream(newFileName);

        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) {
            out.write(buffer, 0, read);
        }
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
    } catch (Exception e) {
        Log.e("tag", e.getMessage());
    }
    new File(newFileName).setExecutable(true, false);
}

1

রোহিত নন্দকুমারের সমাধানের ভিত্তিতে, আমি সম্পদের সাবফোল্ডার (অর্থাত্ "সম্পদ / মাইফোল্ডার ") থেকে ফাইলগুলি অনুলিপি করার জন্য নিজের কিছু করেছি । এছাড়াও, আমি আবারও অনুলিপি করার চেষ্টা করার আগে ফাইলটি এসডকার্ডে ইতিমধ্যে উপস্থিত রয়েছে কিনা তা আমি যাচাই করছি।

private void copyAssets() {
    AssetManager assetManager = getAssets();
    String[] files = null;
    try {
        files = assetManager.list("MyFolder");
    } catch (IOException e) {
        Log.e("tag", "Failed to get asset file list.", e);
    }
    if (files != null) for (String filename : files) {
        InputStream in = null;
        OutputStream out = null;
        try {
          in = assetManager.open("MyFolder/"+filename);
          File outFile = new File(getExternalFilesDir(null), filename);
          if (!(outFile.exists())) {// File does not exist...
                out = new FileOutputStream(outFile);
                copyFile(in, out);
          }
        } catch(IOException e) {
            Log.e("tag", "Failed to copy asset file: " + filename, e);
        }     
        finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // NOOP
                }
            }
        }  
    }
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while((read = in.read(buffer)) != -1){
      out.write(buffer, 0, read);
    }
}

0

এটি এখন পর্যন্ত সেরা সমাধান যা আমি ইন্টারনেটে সন্ধান করতে সক্ষম হয়েছি। আমি নীচের লিঙ্কটি https://gist.github.com/mhasby/026f02b33fcc4207b302a60645f6e217 ব্যবহার করেছি ,
তবে এতে আমার একক ত্রুটি হয়েছিল যা আমি স্থির করেছিলাম এবং এটি তখন মনোযোগের মতো কাজ করে। আমার কোড এখানে। এটি একটি স্বাধীন জাভা শ্রেণি হওয়ায় আপনি সহজেই এটি ব্যবহার করতে পারেন।

public class CopyAssets {
public static void copyAssets(Context context) {
    AssetManager assetManager = context.getAssets();
    String[] files = null;
    try {
        files = assetManager.list("");
    } catch (IOException e) {
        Log.e("tag", "Failed to get asset file list.", e);
    }
    if (files != null) for (String filename : files) {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = assetManager.open(filename);

            out = new FileOutputStream(Environment.getExternalStorageDirectory()+"/www/resources/" + filename);
            copyFile(in, out);
        } catch(IOException e) {
            Log.e("tag", "Failed to copy asset file: " + filename, e);
        }
        finally {
            if (in != null) {
                try {
                    in.close();
                    in = null;
                } catch (IOException e) {

                }
            }
            if (out != null) {
                try {
                    out.flush();
                    out.close();
                    out = null;
                } catch (IOException e) {

                }
            }
        }
    }
}

public static void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while((read = in.read(buffer)) != -1){
        out.write(buffer, 0, read);
    }
}}

আপনি দেখতে পাচ্ছেন, কেবল CopyAssetsআপনার জাভা শ্রেণিতে একটি ক্রিয়াকলাপ রয়েছে এমন একটি উদাহরণ তৈরি করুন । এখন এই অংশটি গুরুত্বপূর্ণ, যতদূর ইন্টারনেটে আমার পরীক্ষা এবং গবেষণা করা যায় You cannot use AssetManager if the class has no activity। জাভা শ্রেণীর প্রসঙ্গে এটির কিছু সম্পর্ক রয়েছে।
এখন, c.copyAssets(getApplicationContext())পদ্ধতিটি অ্যাক্সেস করার সহজ উপায়, যেখানে ক্লাসের cউদাহরণ এবং উদাহরণ CopyAssets। আমার প্রয়োজন অনুসারে, আমি প্রোগ্রামটিকে আমার সমস্ত সংস্থান ফাইলগুলি assetফোল্ডারের ভিতরে /www/resources/আমার অভ্যন্তরীণ ডিরেক্টরিতে অনুলিপি করার অনুমতি দিয়েছি।
আপনার ব্যবহার অনুযায়ী ডিরেক্টরিতে আপনাকে যে অংশটি পরিবর্তন করতে হবে তা আপনি সহজেই সন্ধান করতে পারেন। আপনার যদি কোনও সহায়তার দরকার হয় তবে নির্দ্বিধায় আমাকে পিং করুন।


0

যারা কোটলিনে আপডেট করছেন তাদের জন্য:

এড়াতে এই পদক্ষেপগুলি অনুসরণ করে FileUriExposedExceptions, মনে করুন ব্যবহারকারী WRITE_EXTERNAL_STORAGEঅনুমতি দিয়েছে এবং আপনার ফাইলটি প্রবেশ করেছে assets/pdfs/mypdf.pdf

private fun openFile() {
    var inputStream: InputStream? = null
    var outputStream: OutputStream? = null
    try {
        val file = File("${activity.getExternalFilesDir(null)}/$PDF_FILE_NAME")
        if (!file.exists()) {
            inputStream = activity.assets.open("$PDF_ASSETS_PATH/$PDF_FILE_NAME")
            outputStream = FileOutputStream(file)
            copyFile(inputStream, outputStream)
        }

        val uri = FileProvider.getUriForFile(
            activity,
            "${BuildConfig.APPLICATION_ID}.provider.GenericFileProvider",
            file
        )
        val intent = Intent(Intent.ACTION_VIEW).apply {
            setDataAndType(uri, "application/pdf")
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
        }
        activity.startActivity(intent)
    } catch (ex: IOException) {
        ex.printStackTrace()
    } catch (ex: ActivityNotFoundException) {
        ex.printStackTrace()
    } finally {
        inputStream?.close()
        outputStream?.flush()
        outputStream?.close()
    }
}

@Throws(IOException::class)
private fun copyFile(input: InputStream, output: OutputStream) {
    val buffer = ByteArray(1024)
    var read: Int = input.read(buffer)
    while (read != -1) {
        output.write(buffer, 0, read)
        read = input.read(buffer)
    }
}

companion object {
    private const val PDF_ASSETS_PATH = "pdfs"
    private const val PDF_FILE_NAME = "mypdf.pdf"
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.