Android 将文件导出到SD卡时有一个小问题

Android 将文件导出到SD卡时有一个小问题,android,file-io,Android,File Io,我面临一个问题:我在/data/data/files上存储了数据,并且有一个菜单按钮“export”,当我点击它时,文件在SD卡中很好地导出,但大小为0(文件中没有数据)。 export.class代码: public Export(Context context,String nom) { this.context = context; this.nom=nom; } public void transfer(){ try

我面临一个问题:我在/data/data/files上存储了数据,并且有一个菜单按钮“export”,当我点击它时,文件在SD卡中很好地导出,但大小为0(文件中没有数据)。 export.class代码:

public Export(Context context,String nom) {
        this.context = context;
        this.nom=nom;
       }

    public void transfer(){
        try {
    File sdCard = Environment.getExternalStorageDirectory();
    boolean mExternalStorageAvailable = false;
    boolean mExternalStorageWriteable = false;
    String state = Environment.getExternalStorageState();

    if (Environment.MEDIA_MOUNTED.equals(state)) {
        // We can read and write the media
        Log.d("Carburant", "Sdcard can read/write !!" ); 
        mExternalStorageAvailable = mExternalStorageWriteable = true;
        File dir = new File (sdCard.getAbsolutePath() + "/Carburant/");
        dir.mkdirs();
        File file = new File(dir, "settings.dat");
        //FileOutputStream f = new FileOutputStream(file);
        copyfile(nom,file.getAbsolutePath());
    } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        // We can only read the media
        Log.d("Carburant", "Sdcard only read !!" ); 
        mExternalStorageAvailable = true;
        mExternalStorageWriteable = false;
    } else {
        // Something else is wrong. It may be one of many other states, but all we need
        //  to know is we can neither read nor write
        mExternalStorageAvailable = mExternalStorageWriteable = false;
    }
        }
    catch (Exception e) {
        Log.d("CARBURANT", e.getMessage());
    }

}

    private void copyfile(String srFile, String dtFile){
        try{
            File f1 = new File(srFile);
            File f2 = new File(dtFile);
          InputStream in = new FileInputStream(f1);
          OutputStream out = new FileOutputStream(f2);

          byte[] buf = new byte[1024];
          int len;
          while ((len = in.read(buf)) > 0){
            out.write(buf, 0, len);
          }
          in.close();
          out.close();
          Toast.makeText(context, "Export effectué", Toast.LENGTH_SHORT).show();
        }
        catch(FileNotFoundException ex){
            Toast.makeText(context, "File Not found", Toast.LENGTH_SHORT).show();
            String x=ex.getMessage();
            Log.d("Carburant", x);
        }
        catch(IOException e){
            Toast.makeText(context, "Echec", Toast.LENGTH_SHORT).show();      
        }
      }

    }
在何处写入文件的代码:

if (data != "" ) {
              SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
           String fileName = getResources().getString(R.string.fileName);
           String fileDir = ""+ preferences.getString("login", "") + "."+ preferences.getString("marque", "") + ".";
           myIO.WriteSettings(context,fileDir+fileName, data);
           data = "";
写设置方法:

public static void WriteSettings(Context context, String nom, String data) {
        FileOutputStream fOut = null;
        OutputStreamWriter osw = null;

        try {
            fOut = context.openFileOutput(nom, Context.MODE_APPEND);
            osw = new OutputStreamWriter(fOut);
            osw.write(data);
            osw.flush();
            osw.close();
                    fOut.close();
菜单导出按钮:

case R.id.export:
    String mainDirPath = this.getFilesDir() + File.separator + "settings.dat";
    FileOutputStream fos;
    try {
        fos = this.openFileOutput("settings.dat", Context.MODE_PRIVATE);
        Export myExport = new Export(this,mainDirPath);
        myExport.transfer();
    } catch (FileNotFoundException e) {
        Log.d("Carburant","File Not found");
    }catch(IOException e){
        Log.d("Carburant","ERROR");
    }
            return true;
case R.id.exporter:
            final SharedPreferences preferences = PreferenceManager
            .getDefaultSharedPreferences(context);
    String fileName = getResources().getString(R.string.fileName);
    fileDir = "" + preferences.getString("login", "") + "."+ preferences.getString("marque", "") + ".";

    String mainDirPath = this.getFilesDir() + File.separator + fileDir+fileName;
    Log.d("Carburant",mainDirPath);
    FileOutputStream fos;
    try {
        fos = this.openFileOutput(fileDir+fileName, Context.MODE_PRIVATE);
        Export myExport = new Export(this,mainDirPath);
        myExport.transfer();
    } catch (FileNotFoundException e) {
        Log.d("Carburant","File Not found");
    }catch(IOException e){
        Log.d("Carburant","ERROR");
    }
            return true;
编辑菜单导出按钮:

case R.id.export:
    String mainDirPath = this.getFilesDir() + File.separator + "settings.dat";
    FileOutputStream fos;
    try {
        fos = this.openFileOutput("settings.dat", Context.MODE_PRIVATE);
        Export myExport = new Export(this,mainDirPath);
        myExport.transfer();
    } catch (FileNotFoundException e) {
        Log.d("Carburant","File Not found");
    }catch(IOException e){
        Log.d("Carburant","ERROR");
    }
            return true;
case R.id.exporter:
            final SharedPreferences preferences = PreferenceManager
            .getDefaultSharedPreferences(context);
    String fileName = getResources().getString(R.string.fileName);
    fileDir = "" + preferences.getString("login", "") + "."+ preferences.getString("marque", "") + ".";

    String mainDirPath = this.getFilesDir() + File.separator + fileDir+fileName;
    Log.d("Carburant",mainDirPath);
    FileOutputStream fos;
    try {
        fos = this.openFileOutput(fileDir+fileName, Context.MODE_PRIVATE);
        Export myExport = new Export(this,mainDirPath);
        myExport.transfer();
    } catch (FileNotFoundException e) {
        Log.d("Carburant","File Not found");
    }catch(IOException e){
        Log.d("Carburant","ERROR");
    }
            return true;

谢谢您的帮助。

我建议在调试器中单步执行此操作,并查看copyfile方法中发生的情况。src文件“nom”是否存在,大小是否为非零

致以最良好的祝愿


Phil Lello

我建议在调试器中单步执行此操作,并查看copyfile方法中发生的情况。src文件“nom”是否存在,大小是否为非零

致以最良好的祝愿


菲尔·莱洛(Phil Lello)

也许可以看看这行“while((len=in.read(buf))>0”


也许可以看看这行“while((len=in.read(buf))>0”


在您的菜单中,上面的导出按钮代码中,您正在执行此操作

case R.id.export:
    String mainDirPath = this.getFilesDir() + File.separator + "settings.dat";
这意味着mainDirPath将类似于

/data/data/<package name>/files/settings.dat
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String mainDirPath = this.getFilesDir() + File.separator + preferences.getString("login", "") + "." + preferences.getString("marque", "") + "." + "settings.dat";
这意味着,当您创建mainDirPath时,它应该类似于

/data/data/<package name>/files/settings.dat
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String mainDirPath = this.getFilesDir() + File.separator + preferences.getString("login", "") + "." + preferences.getString("marque", "") + "." + "settings.dat";
混乱的是这条线

fos = this.openFileOutput("settings.dat", Context.MODE_PRIVATE);
…这将创建一个名为

/data/data/<package name>/files/settings.dat
/data/data//files/settings.dat
该文件是您正在复制的文件,而不是名为
login.marque.settings.dat的文件


这有意义吗?

在菜单上方的导出按钮代码中,您正在执行此操作

case R.id.export:
    String mainDirPath = this.getFilesDir() + File.separator + "settings.dat";
这意味着mainDirPath将类似于

/data/data/<package name>/files/settings.dat
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String mainDirPath = this.getFilesDir() + File.separator + preferences.getString("login", "") + "." + preferences.getString("marque", "") + "." + "settings.dat";
这意味着,当您创建mainDirPath时,它应该类似于

/data/data/<package name>/files/settings.dat
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String mainDirPath = this.getFilesDir() + File.separator + preferences.getString("login", "") + "." + preferences.getString("marque", "") + "." + "settings.dat";
混乱的是这条线

fos = this.openFileOutput("settings.dat", Context.MODE_PRIVATE);
…这将创建一个名为

/data/data/<package name>/files/settings.dat
/data/data//files/settings.dat
该文件是您正在复制的文件,而不是名为
login.marque.settings.dat的文件



这有意义吗?

@pḧil Lello:还有,让我抓狂的事情,我现在检查了/data/data中的文件。。。。使用DDMS,并发现其大小为0!为什么它有0?毫无疑问,它在存储数据,上面有内容,但为什么是0!我重新启动应用程序,数据仍然在这里。有什么问题吗?谢谢。如果不单步查看复制失败的地方,很难说,但我怀疑路径在某个地方被弄乱了,而你没有复制你认为是的文件。@Phil Lello:你有绝对的理由,路径上有些“奇怪”的东西!我真的觉得主要问题就出在这里:\@androniennn:在尝试读取/导出源文件之前,您是在源文件上使用flush()和/或close()吗?如果使用BufferedWriter(例如),则文件将存在,但在调用flush()之前,数据不会“刷新”(写入)到文件中。如果在尝试复制之前对文件对象使用close(),这将自动完成。@MisterSquonk:是的,在向文件添加数据时,我有flush()。但正如您在上面看到的,我认为我不必在copyfile函数中使用flush。@Pḧil Lello:还有,让我抓狂的事情,我现在检查了/data/data中的文件。。。。使用DDMS,并发现其大小为0!为什么它有0?毫无疑问,它在存储数据,上面有内容,但为什么是0!我重新启动应用程序,数据仍然在这里。有什么问题吗?谢谢。如果不单步查看复制失败的地方,很难说,但我怀疑路径在某个地方被弄乱了,而你没有复制你认为是的文件。@Phil Lello:你有绝对的理由,路径上有些“奇怪”的东西!我真的觉得主要问题就出在这里:\@androniennn:在尝试读取/导出源文件之前,您是在源文件上使用flush()和/或close()吗?如果使用BufferedWriter(例如),则文件将存在,但在调用flush()之前,数据不会“刷新”(写入)到文件中。如果在尝试复制之前对文件对象使用close(),这将自动完成。@MisterSquonk:是的,在向文件添加数据时,我有flush()。但正如您在上面看到的,我认为我不必在copyfile函数中使用flush。@达斯:有什么建议吗?谢谢你。@Dasiths:这是我做的,但我的尺寸总是0。我认为问题来自/data/data中的文件!但是怎么做呢?如果它的大小为0=>没有内容=>没有读取数据。:\n我不认为len>0的测试会导致这种情况。。。InputStream.read的-1与0的区别对于交互流更为相关,其中“现在没有数据”与“将没有更多数据”不同。对于文件支持的输入流,0字节的读取只会发生在文件末尾,或者源文件为空。当然,测试-1更好。@andrinienn既然我们现在知道了问题所在,就编写一个单独的函数来读取文件内容并进行调试。我不确定,但字节数组大小是否足以容纳文件内容?@Dasiths:我有一个函数,可以读取文件内容(每行一行)以在列表视图中显示。@Dasiths:有什么建议吗?谢谢你。@Dasiths:这是我做的,但我的尺寸总是0。我认为问题来自/data/data中的文件!但是怎么做呢?如果它的大小为0=>没有内容=>没有读取数据。:\n我不认为len>0的测试会导致这种情况。。。InputStream.read的-1与0的区别对于交互流更为相关,其中“现在没有数据”与“将没有更多数据”不同。对于文件支持的输入流,0字节的读取只会发生在文件末尾,或者源文件为空。当然,测试-1更好。@andrinienn既然我们现在知道了问题所在,就编写一个单独的函数来读取文件内容并进行调试。我不确定,但字节数组大小是否足以容纳文件内容?@Dasiths:我有一个函数,可以读取文件内容(每行一行)以在Listview中显示它