Android写入日志文本文件

时间:2009-11-18 14:17:35

标签: android

我正在尝试使用Mine的代码将日志写入Android文件上的自定义Log.txt文件,但此方法创建文件但不包含任何内容。基本上我想读取文件的先前内容,然后用现有内容附加我的数据。

守则如下:

public static void write(String str) 
    {
        InputStream fileInputStream = null;
        FileOutputStream fileOutpurStream = null;
        try
        { 
            fileInputStream = new FileInputStream(file);
            fileOutpurStream = new FileOutputStream(file);
            if(file.exists())
            {
                int ch = 0;
                int current = 0;
                StringBuffer buffer = new StringBuffer();
                while((ch = fileInputStream.read()) != -1)
                {
                    buffer.append((char) ch);
                    current++;
                }
                byte data[]=new byte[(int)file.length()];
                fileInputStream.read(data);   
                fileOutpurStream.write(data);
                fileOutpurStream.write(str.getBytes(),0,str.getBytes().length);
                fileOutpurStream.flush();
            } 
            else
            {   
                file.createNewFile();
                fileOutpurStream.write(str.getBytes(),0,str.getBytes().length);
                fileOutpurStream.flush();
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                fileInputStream.close();
                fileOutpurStream.flush();
                fileOutpurStream.close();
                fileOutpurStream = null;
                fileInputStream = null;
            }
            catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

16 个答案:

答案 0 :(得分:236)

希望这可以帮助...

public void appendLog(String text)
{       
   File logFile = new File("sdcard/log.file");
   if (!logFile.exists())
   {
      try
      {
         logFile.createNewFile();
      } 
      catch (IOException e)
      {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
   try
   {
      //BufferedWriter for performance, true to set append to file flag
      BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
      buf.append(text);
      buf.newLine();
      buf.close();
   }
   catch (IOException e)
   {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
}

答案 1 :(得分:26)

对于那些刚接触Java日志记录和Android日志记录的人

  1. Log4j是通用的Java日志记录实现,现在是一个项目 Apache软件基础。它不是Android特有的 与Android有些不兼容。
  2. SL4J不是日志记录实现,它是一个抽象层。它 有助于避免每个第三方库的情况 依赖于项目,尝试使用自己的日志记录 像Log4j这样的实现。 Source
  3. 在Android中记录到txt的一些选项位于

    之下
    1. 使用此answer中的logcat -f来登录文件。请注意 Android 4.2,READ_LOGS权限不会产生任何影响 应用程序(除非手机已植根)只能读取自己的日志。 这里的缺点是logcat缓冲区是圆形的并且有一个大小 限制。您可能无法获得更早的日志。
    2. 使用microlog4android(为Android等移动设备编写) 早先answer。可能有办法,但我不知道如何 使用microlog4Android记录到应用程序内部存储。 只有日志路径的选项是外部存储,如SD卡,所以我 无法使用它。
    3. Log4jandroid-logging-log4j一起使用。是什么 android-logging-log4j呢?这使得Log4j更易于在Android中使用 通过赋予两个功能。

      • 除了记录文件
      • 之外还将日志发送到logcat的选项
      • 通过提供LogConfigurator类,设置Log4j配置选项(如文件路径,最大文件大小,备份数量等)的简单方法。

      以下简单示例。请注意,下面示例中的logger对象是返回的Log4j对象,而不是android-logging-log4j类。所以android-logging-log4j仅用于配置Log4j。

    4. 然后尝试LogBack。 LogBack是由同一个人开发的 想出了Log4J 1.x和SL4J库。与Log4j 2.x无关 虽然。
    5. 在Android中使用Log4j的步骤。

      1. 同时添加log4j-1.2.x.jarandroid-logging-log4j-1.0.3.jar libs文件夹。

      2. 仅在使用外部存储时添加权限
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

      3. 撰写Log4j助手类

        package com.example.logger;
        
        import android.os.Environment;
        import de.mindpipe.android.logging.log4j.LogConfigurator;
        
        public class Log4jHelper {
            private final static LogConfigurator mLogConfigrator = new LogConfigurator();
        
            static {
                configureLog4j();
            }
        
            private static void configureLog4j() {
                String fileName = Environment.getExternalStorageDirectory() + "/" + "log4j.log";
                String filePattern = "%d - [%c] - %p : %m%n";
                int maxBackupSize = 10;
                long maxFileSize = 1024 * 1024;
        
                configure( fileName, filePattern, maxBackupSize, maxFileSize );
            }
        
            private static void configure( String fileName, String filePattern, int maxBackupSize, long maxFileSize ) {
                mLogConfigrator.setFileName( fileName );
                mLogConfigrator.setMaxFileSize( maxFileSize );
                mLogConfigrator.setFilePattern(filePattern);
                mLogConfigrator.setMaxBackupSize(maxBackupSize);
                mLogConfigrator.setUseLogCatAppender(true);
                mLogConfigrator.configure();
        
            }
        
            public static org.apache.log4j.Logger getLogger( String name ) {
                org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger( name );
                return logger;
            }
        }
        
      4. 在Activity类

        org.apache.log4j.Logger log= Log4jHelper.getLogger( "YourActivity" );
        log.error("Error");
        log.info("Info");
        log.warn("Warn");
        
      5. Example Source。请注意,从头开始重写的log4j 2.x(改进的功能)与log4j 1.x无法向后兼容。所以你必须使用log4j 1.2.x jar和android-logging-log4j jar。我能够登录到应用程序内部文件,然后使用setReadable(true, false)

        通过电子邮件发送文件

答案 2 :(得分:23)

microlog4android对我有用,但文档很差。他们需要添加的只是一个快速启动tutorial

这是我发现的快速教程。

  1. 在主Activity中添加以下静态变量:

    private static final Logger logger = LoggerFactory.getLogger();
    
  2. 将以下内容添加到onCreate()方法中:

    PropertyConfigurator.getConfigurator(this).configure();
    
  3. 创建名为microlog.properties的文件并将其存储在assets目录

  4. 按如下方式编辑microlog.properties文件:

    microlog.level=DEBUG
    microlog.appender=LogCatAppender;FileAppender
    microlog.formatter=PatternFormatter
    microlog.formatter.PatternFormatter.pattern=%c [%P] %m %T
    
  5. 添加如下记录语句:

    logger.debug("M4A");
    
  6. 对于每个类,您可以创建1)

    中指定的记录器对象

    6.您可以添加以下权限:

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    以下是教程的source

答案 3 :(得分:11)

警告:我可能完全误解了你,但如果你想要的只是一个日志文件,为什么会出汗?

将它放在一个bat文件中(更改工具目录的路径,yourappname当然是你的应用程序名称):

cd "C:\devAndroid\Software\android-sdk-windows-1.6_r1\android-sdk-windows-1.6_r1\tools"
adb logcat -v time   ActivityManager:W  yourappname:D  *:W >"C:\devAndroid\log\yourappname.log"

然后在您的代码中执行类似的操作:

Log.d("yourappname", "Your message");

要创建日志,请连接USB电缆并运行您的bat文件。

此致

答案 4 :(得分:7)

你应该看看microlog4android。他们有一个准备好登录文件的解决方案。

http://code.google.com/p/microlog4android/

答案 5 :(得分:7)

这可能会迟到但希望这可能会有所帮助.. 试试这个....

public void writefile()
    {
        File externalStorageDir = Environment.getExternalStorageDirectory();
        File myFile = new File(externalStorageDir , "yourfilename.txt");

        if(myFile.exists())
        {
           try
           {

        FileOutputStream fostream = new FileOutputStream(myFile);
        OutputStreamWriter oswriter = new OutputStreamWriter(fostream); 
        BufferedWriter bwriter = new BufferedWriter(oswriter);   
        bwriter.write("Hi welcome ");
        bwriter.newLine();            
        bwriter.close(); 
        oswriter.close(); 
        fostream.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
        else
        {
            try {
                myFile.createNewFile();
            }
            catch (IOException e) 
            {
                e.printStackTrace();
            }
        }

此处bfwritter.newline将您的文字写入文件。并添加权限

 <uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
您的清单文件中的

没有失败。

答案 6 :(得分:7)

使用slf4android lib。
这是使用android java.util.logging。*。

slf4j api的简单实现

特点:

  • 开箱即用的文件
  • LoggerConfiguration.configuration().addHandlerToLogger
  • 登录任何其他目的地
  • 摇动您的设备,通过电子邮件发送带有屏幕截图的日志
  • 真的很小,只花了~55kB

slf4android主要由@miensol维护。

在我们的博客上阅读有关slf4android的更多信息:

答案 7 :(得分:5)

我用命令行方式用以下代码解决了这个问题:

File outputFile = new File("pathToFile"); 
Runtime.getRuntime().exec("logcat -c");
Runtime.getRuntime().exec("logcat -v time -f " + outputFile.getAbsolutePath())

其中&#34;时间&#34; option为发布消息的进程添加日期,调用时间,优先级/标记和PID的元数据字段详细信息。

然后在你的代码中做一些与此类似的事情(使用android.util.Log):

Log.d("yourappname", "Your message");

答案 8 :(得分:2)

通常,在打开流之前必须有文件句柄。在else块中的 createNewFile()之前有一个fileOutputStream句柄。如果文件不存在,则流不会创建该文件。

不是特定于Android特定的,但为此目的,这是很多IO。如果你一个接一个地做很多“写”操作怎么办?您将阅读全部内容并撰写全部内容,花费时间,更重要的是电池寿命。

我建议使用java.io.RandomAccessFile,seek()'到最后,然后使用writeChars()来追加。这将是更清晰的代码,可能更快。

答案 9 :(得分:2)

我创建了一个简单的轻量级类(约260 LoC),它扩展了基于文件的日志记录的标准android.util.Log实现:
每条日志消息都通过android.util.Log记录,并写入设备上的文本文件。

你可以在github上找到它:
https://github.com/volkerv/FileLog

答案 10 :(得分:2)

经过长时间的调查,我发现:

  • android.util.Log默认使用java.util.logging.Logger
  • LogCat使用名称为logger的{​​{1}},使用""来获取其实例
  • 运行调试应用后,Android设备将添加到LogManager.getLogManager().getLogger("")的LogCat logger实例中
  • 但是!!! com.android.internal.logging.AndroidHandler仅将级别高于com.android.internal.logging.AndroidHandler的消息(例如(java.util.logging.Level.INFO)打印到logcat

因此要将日志写入文件,只需向Level.INFO, Level.WARNING, Level.SEVERE, Level.OFF rootLogger添加一个""

java.util.logging.FileHandler
  class App : Application{
    override fun onCreate() {
      super.onCreate()
      Log.d(TAG, printLoggers("before setup"))

      val rootLogger = java.util.logging.LogManager.getLogManager().getLogger("")
      val dirFile = destinationFolder
      val file = File(dirFile,"logFile.txt")
      val handler = java.util.logging.FileHandler(file.absolutePath, 5* 1024 * 1024/*5Mb*/, 1, true)
      handler.formatter = AndroidLogFormatter(filePath = file.absolutePath)

      rootLogger?.addHandler(handler)

      Log.d(TAG, printLoggers("after setup"))
    }
  }

val destinationFolder: File
        get() {
            val parent = 
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absoluteFile
            val destinationFolder = File(parent, "MyApp")
            if (!destinationFolder.exists()) {
                destinationFolder.mkdirs()
                destinationFolder.mkdir()
            }
            return destinationFolder
        }

要使用您的应用程序打印所有记录器,请执行以下操作:

class AndroidLogFormatter(val filePath: String = "", var tagPrefix: String = "") : Formatter() {

    override fun format(record: LogRecord): String {
        val tag = record.getTag(tagPrefix)
        val date = record.getDate()
        val level = record.getLogCatLevel()
        val message = record.getLogCatMessage()
        return "$date $level$tag: $message\n"
    }
}

fun LogRecord.getTag(tagPrefix: String): String {
    val name = loggerName
    val maxLength = 30
    val tag = tagPrefix + (if (name.length > maxLength) name.substring(name.length - maxLength) else name)
    return tag
}

fun LogRecord.getDate(): String? {
    return Date(millis).formatedBy("yyyy-MM-dd HH:mm:ss.SSS")
}

fun Date?.formatedBy(dateFormat: String): String? {
    val date = this
    date ?: return null
    val writeFormat = SimpleDateFormat(dateFormat, Locale.getDefault()) //MM в HH:mm
    return writeFormat.format(date)
}

fun LogRecord.getLogCatMessage(): String {
    var message = message

    if (thrown != null) {
        message += Log.getStackTraceString(thrown)
    }
    return message
}

fun Int.getAndroidLevel(): Int {
    return when {
        this >= Level.SEVERE.intValue() -> { // SEVERE
            Log.ERROR
        }
        this >= Level.WARNING.intValue() -> { // WARNING
            Log.WARN
        }
        this >= Level.INFO.intValue() -> { // INFO
            Log.INFO
        }
        else -> {
            Log.DEBUG
        }
    }
}

fun LogRecord.getLogCatLevel(): String {
    return when (level.intValue().getAndroidLevel()) {
        Log.ERROR -> { // SEVERE
            "E/"
        }
        Log.WARN -> { // WARNING
            "W/"
        }
        Log.INFO -> { // INFO
            "I/"
        }
        Log.DEBUG -> {
            "D/"
        }
        else -> {
            "D/"
        }
    }
}

fun getLoggerLevel(level: Int): Level {
    return when (level) {
        Log.ERROR -> { // SEVERE
            Level.SEVERE
        }
        Log.WARN -> { // WARNING
            Level.WARNING
        }
        Log.INFO -> { // INFO
            Level.INFO
        }
        Log.DEBUG -> {
            Level.FINE
        }
        else -> {
            Level.FINEST
        }
    }
}

答案 11 :(得分:1)

此变体要短得多

try {
    final File path = new File(
            Environment.getExternalStorageDirectory(), "DBO_logs5");
    if (!path.exists()) {
        path.mkdir();
    }
    Runtime.getRuntime().exec(
            "logcat  -d -f " + path + File.separator
                    + "dbo_logcat"
                    + ".txt");
} catch (IOException e) {
    e.printStackTrace();
}

答案 12 :(得分:0)

您可以使用我编写的库。 它非常易于使用:

将此依赖项添加到您的gradle文件中:

dependencies {
    compile 'com.github.danylovolokh:android-logger:1.0.2'
}

在Application类中初始化库:

File logsDirectory = AndroidLogger.getDefaultLogFilesDirectory(this);
    int logFileMaxSizeBytes = 2 * 1024 * 1024; // 2Mb
    try {
        AndroidLogger.initialize(
                this,
                logsDirectory,
                "Log_File_Name",
                logFileMaxSizeBytes,
                false
                );
    } catch (IOException e) {
        // Some error happened - most likely there is no free space on the system
    }

以下是您使用该库的方式:

AndroidLogger.v("TAG", "Verbose Message");

以下是检索日志的方法:

AndroidLogger.processPendingLogsStopAndGetLogFiles(new AndroidLogger.GetFilesCallback() {
        @Override
        public void onFiles(File[] logFiles) {
            // get everything you need from these files
            try {
                AndroidLogger.reinitAndroidLogger();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

以下是github页面的链接,其中包含更多信息: https://github.com/danylovolokh/AndroidLogger

希望它有所帮助。

答案 13 :(得分:0)

log4j上的许多先前版本现在不起作用(05/2019)。但是您可以使用Hyperlog-我可以确认它是否有效。

  1. 将此行添加到您的依赖项和同步项目中

    [{
        "id": "8D5D-4CD323560F59",
        "x": 40.7128,
        "y": -74.0060
     },{
        "id": "E3E0D2C5-CB82",
        "x": 41.7128,
        "y": -75.0060
     }]
    
  2. 创建一个新的应用程序类(创建一个新的Java类并扩展Application)。然后在onCreate方法中添加以下行:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    
    public class CodeGenerator {
    
    private JFrame f;
    private JPanel p;
    private JPanel p2;
    private JPanel p3;
    private JButton butt;
    private JLabel lab; 
    
    public CodeGenerator() {
        gui();
    }
    
    public void gui() {
        f = new JFrame ("Code generator");
        f.setVisible(true);
        f.setSize(600,400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        p = new JPanel();
        p.setBackground(Color.WHITE);
    
        p2 = new JPanel();
        p2.setBackground(Color.DARK_GRAY);
    
    
        butt = new JButton("Generate");
        butt.addActionListener(new ActionListener() { 
            public void actionPerformed(ActionEvent e) {
    
                CodeAlgorythm codegen = new CodeAlgorythm();
                codegen.generateCode();
                  //The code over here is the code generator
            } 
        });
    
        lab = new JLabel("This program is designed to generate random codes 
    to help you protect your datas.");
    
    
        p2.add(butt);
    
        p.add(lab);
    
        f.add(p,BorderLayout.CENTER);
    
        f.add(p2,BorderLayout.SOUTH);
        //Up there is all the GUI stuff
    
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
            new CodeGenerator();
    
    }
    
    }
    
  3. 更改清单文件以定义应用程序文件。

    implementation 'com.hypertrack:hyperlog:0.0.10'
    
  4. 不同的登录方式:

    HyperLog.initialize(this);
    HyperLog.setLogLevel(Log.VERBOSE);
    
    HyperLog.getDeviceLogsInFile(this);
    
  5. 查找您的日志文件。导航到

    <application
        android:name=".AppClass"
        .....
    

答案 14 :(得分:0)

    File logFile = new File(filename);
    try { 
    Process process = Runtime.getRuntime().exec("logcat AndroidRuntime:E *:S 
    -f " + logFile);
    } 
    catch ( Exception e ) 
    { Basic.Logger("Error Basic", "error "+e); }

尝试使用此代码在文件中写入错误日志

答案 15 :(得分:-2)

public void appendLog(String text)
{       
   File logFile = new File("sdcard/log.file.txt");
   if (!logFile.exists())
   {
      try
      {
         logFile.createNewFile();
      } 
      catch (IOException e)
      {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
   try
   {
      //BufferedWriter for performance, true to set append to file flag
      BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true)); 
      buf.append(text);
      buf.newLine();
      buf.close();
   }
   catch (IOException e)
   {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
}