【问题标题】:Writing String to Text File将字符串写入文本文件
【发布时间】:2014-08-31 23:33:11
【问题描述】:

我正在将日志保存到 sdcard 上的 .txt 文件中,但是一旦保存了两行,它就会覆盖它并重新开始?

这是我的代码:

public static String getTimestamp() {
    try {

        SimpleDateFormat dateFormat = new SimpleDateFormat("MMMdd HH:mm:ss", Locale.getDefault());
        String currentTimeStamp = dateFormat.format(new Date()); // Find todays date

        return currentTimeStamp;
    } catch (Exception e) {
        e.printStackTrace();

        return null;
    }
}

public static void writeToLog(Context context, String string) {
    String text = getTimestamp() + " " + string;
    // ONLY SAVES TWO LINES
    try {
        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(logFile, true)));
        out.println(text);
        out.close();
    } catch (IOException e) {
        Log.d(Constants.APP_NAME, e.toString());
    }
}

在恢复中挂载 /data 后,/sdcard 和 /data/media/0 中的日志文件会显示完整的日志历史记录,但不会在设备开机时显示

【问题讨论】:

  • 之前没有使用过 PrintWriter,但您是否尝试过使用 print 而不是 println
  • @zgc7009 我认为这不是问题,因为操作员说两行已保存,但它会覆盖并加注星号
  • 我想知道PrintWriter 中是否丢失了异常。调用out.checkError(),看看是否返回true。
  • 你试过 printWriter.append() 吗?
  • @arayray 作为问题发布者,您应该能够对发布在您问题上的任何答案发表评论。

标签: java android bufferedwriter


【解决方案1】:

您可以简单地使用FileWriter 而无需所有链接的其他作者。请务必调用flush(),因为这样可以确保将所有缓冲内容写入文件。
如果这仍然不起作用,请检查错误输出。

public static void writeToLog(Context context, String string) {
    String text = getTimestamp() + " " + string + "\n"; //newline here

    Writer out;
    try {
        out = new FileWriter(logFile, true);
        out.append(text);
        out.flush();        //ensure that all buffered characters are written to the target
    } catch (IOException e) {
        Log.d(Constants.APP_NAME, e.toString());
    } finally {
        if (out != null) {
            out.close();    //ensure writer is closed
        }
    }
}

【讨论】:

  • 关闭 Writer 会刷新它。
【解决方案2】:

使用 NIO,您可以更高效地写入文件末尾

public static void writeToLog(String string) {
   String text = getTimestamp() + " " + string;

   try {
      java.nio.file.Files.write(java.nio.file.Paths.get("/file.txt"), text.getBytes(), java.nio.file.StandardOpenOptions.APPEND);
   } catch (IOException ignore) { }
}

【讨论】:

    【解决方案3】:

    这就是它的完成方式。以下示例代码在单击提交按钮时将详细信息保存到文件中:

    Submit = (Button) findViewById(R.id.btnSubmit); //Instantiates the button in the onCreate method 
            Submit.setOnClickListener(new OnClickListener(){  //Called when the user clicks on the Submit button
    
                @Override
                public void onClick(View v) {
                // In this case the text to be written is the selected text in a radio button from radioGroup
                    int Selection = AttendanceGroup.getCheckedRadioButtonId();
    
                    // find the radiobutton by returned id 
                    RadioButton radiobutton = (RadioButton) findViewById(Selection); 
    
                        // write on SD card file data in the text box
                        try {
    
                            //gets the current date since this is an attendance app.
                            Calendar c = Calendar.getInstance();
                            //Formats the date a desired
                            SimpleDateFormat date = new SimpleDateFormat("dd-MM-yy");
                            String getDate = date.format(c.getTime());
    
                            //writes the text to the file named attendance.txt which is created in the phone.
                            File myFile = new File("/sdcard/Albanapp/Attendance.txt");
                            FileWriter fOut = new FileWriter(myFile, true);
                            fOut.append(getDate + "\t" + getSelectedName.getSelectedItem().toString() + "\t" + radiobutton.getText().toString() + "\n");
                            fOut.flush();
                            fOut.close();
    
                            //Returns a statment to the user showing if the editing of the attendance.txt file was successful or not.  
                            Toast.makeText(getBaseContext(),"Status Saved", Toast.LENGTH_SHORT).show();
                        } catch (Exception e) {
                            Toast.makeText(getBaseContext(), "Attendance cannot be saved",
                                    Toast.LENGTH_SHORT).show();
                        }
                }
            });
    

    希望这会有所帮助:)

    【讨论】:

    • 谢谢!它奏效了,我给了你赏金。再次感谢您
    【解决方案4】:

    我可以使用您的代码附加文件,请您检查此代码

        import java.io.BufferedWriter;
        import java.io.FileWriter;
        import java.io.IOException;
        import java.io.PrintWriter;
        import java.util.Date;
        import java.text.SimpleDateFormat;
        import java.util.Locale;
    
        public class Test {
            public static String getTimestamp() {
                try {
    
                    SimpleDateFormat dateFormat = new SimpleDateFormat(
                            "MMMdd HH:mm:ss", Locale.getDefault());
                    String currentTimeStamp = dateFormat.format(new Date());
    
                    return currentTimeStamp;
                } catch (Exception e) {
                    e.printStackTrace();
    
                    return null;
                }
            }
    
            public static void writeToLog(String string) {
                String text = getTimestamp() + " " + string;
                // ONLY SAVES TWO LINES
                try {
                    PrintWriter out = new PrintWriter(new BufferedWriter(
                            new FileWriter("c:/log.txt", true)));
                    out.println(text);
                    out.close();
                } catch (IOException e) {
                }
            }
    
            public static void main(String[] args) throws Exception {
                writeToLog("Connected to WIFI");
    
            }
        }
    

    输出:
    Sep05 16:13:28 连接到 WIFI
    Sep05 16:13:48 连接到 WIFI
    Sep05 16:13:49 连接到 WIFI
    Sep05 16:13:50 连接到WIFI
    Sep05 16:15:54 连接到 WIFI
    Sep05 16:15:55 连接到 WIFI
    Sep05 16:15:55 连接到 WIFI
    Sep05 16:15:56 连接到 WIFI
    Sep05 16:15:57 连接到 WIFI
    Sep05 16:15:58 连接到 WIFI
    Sep05 16:15:59 连接到 WIFI
    Sep05 16:16:01 连接到 WIFI

    【讨论】:

      【解决方案5】:

      您只调用了一次写入,并且您想立即写入文件。您不需要 BufferedWriter 或 PrintWriter。他们在头顶。此外,应该从 finally{} 块调用 close,因为如果出现错误,您仍然需要关闭它。

      public static void writeToLog(Context context, String string) {
          String text = getTimestamp() + " " + string + "\n";
          Writer out = null;
          try {
              out = new FileWriter(logFile, true);
              out.write(text, 0, text.length());
          } catch (IOException e) {
              Log.d(Constants.APP_NAME, e.toString());
          } finally {
              if (out != null){
                  out.close();
              }
          }
      }
      

      仅当您要在文件打开时进行多次写入时才声明 BufferedWriter。 BufferedWriter 的目的是通过跟踪已输入的内容与已刷新的内容来提高多次写入的效率。

      我看到的另一个问题是,因为这是一个静态方法并且编写器不是静态的,所以多个调用可能会尝试同时调用 writeToLog。

      如果您使用的是 Java 7 或更高版本,您可以使用 try with resources 语句自动关闭您的编写器来简化这一切:

      public static void writeToLog(Context context, String string) {
          String text = getTimestamp() + " " + string + "\n";
          try (FileWriter out = new FileWriter(logFile, true)) {
              out.write(text, 0, text.length());
          } catch (IOException e) {
              Log.d(Constants.APP_NAME, e.toString());
          }
      }
      

      如果您要每秒记录行可能多次,您可能需要考虑保持写入器打开,因为打开/关闭会导致大量开销。它还确保您对 writeToLog() 的所有调用都按顺序发送到同一个编写器。

      private static final PrintWriter logWriter = 
          new PrintWriter(new BufferedWriter(new FileWriter(logFile, true)));
      
      private static int flushCounter = 0;
      private static final int flushFrequency = 5; // Flush the buffer every 5 lines
      
      public static void writeToLog(Context context, String string) {
          String text = getTimestamp() + " " + string + "\n";
          try {
              logWriter.write(text, 0, text.length());
          } catch (IOException e) {
              Log.d(Constants.APP_NAME, e.toString());
          } finally {
              flushCounter++;
              if (flushCounter > flushFrequency){ // flush every 5 lines
                  logWriter.flush();
                  flushCounter = 0;
              }
          }
      }
      
      public void close(){
          logWriter.close();
      }
      

      您可以从调用代码中的 finally{} 块调用 close() 来清理您的 logWriter。

      【讨论】:

      • 我想你可能错过了最重要的部分。我可能有点啰嗦,而且它在帖子中发生了一点。最重要的是,您需要将对 close() 的调用移动到 finally{} 块中,如我上面的第一个示例所示。
      【解决方案6】:

      尝试改变

      PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(logFile, true)));
      

      FileWriter fileWritter = new FileWriter(logFile,true); //true = append file
      BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
      bufferWritter.write(YourData);
      bufferWritter.close();
      

      【讨论】:

      • 我按照建议做了,但它仍然做同样的事情。
      • 我刚刚对我的答案进行了编辑,就像这样,类 FileWriter(File file, boolean append),有 2 个参数文件路径,如果你想附加内容,它应该可以使用我在本地对其进行了测试并且可以正常工作。
      • 尝试更改它为什么?您在这里没有发现任何实际问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-06
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      相关资源
      最近更新 更多