关于System.out重定向到文件的问题

georgeqp 2007-12-26 01:05:50
我打算将System.out和System.err重定向到日志文件
想实现这样的功能
1.把通过system.out.print还有系统抛出的报错信息全部写到日志里面去
2.每次程序重新运行的时候,新的信息是追加在日志以前信息后面的
写了这样一个方法
public static void setSystemOut2LogFile(){
// 在文件上建立一个PrintStream
final String logfile = "111.txt";
File fl = new File(logfile);
try{
PrintStream myout = new PrintStream(new FileOutputStream(fl)){
public void println(String str){
write2File(logfile,readFile(logfile)+"\r\n"+str+"\r\n","GBK");//注:这里我打算重载println函数的,发现还是不行
}
};
// 重定向System.out 到该文件
System.setOut(myout);
System.setErr(myout);
}
catch(Exception ee){
ee.printStackTrace();
}
}

main函数里面调用了这个方法

调试的时候发现
每次重新运行程序的时候,执行到PrintStream myout = new PrintStream(new FileOutputStream(fl)这句的时候,会把文件全清了,之前的日志全没了
对io不是很熟,希望高手指点下,如何在之前的文件上实现追加信息?
...全文
504 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
healer_kx 2008-01-04
  • 打赏
  • 举报
回复
package ***;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

class LoggerHelper {

private File file = null;

public LoggerHelper(String fileName) {
file = new File(fileName);
}


public void log(String message) {
try {

if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file, true);
fw.write(message);


fw.close();
} catch (FileNotFoundException e) {
Logger.doLog("d:\\err.log", e.getMessage());
//e.printStackTrace();
} catch (IOException e) {

Logger.doLog("d:\\err.log", e.getMessage());
}


}

}
public class Logger {




//private static Map<String, LoggerHelper> m = new TreeMap<String, LoggerHelper>();
private static Map m = new TreeMap();

public static void doLog(String fileName, String message) {

LoggerHelper lh = null;
if (m.containsKey(fileName)) {
lh = (LoggerHelper) m.get(fileName);
lh.log(message);
} else {
lh = new LoggerHelper(fileName);
m.put(fileName, lh);
lh.log(message);
}
}
}
healer_kx 2008-01-04
  • 打赏
  • 举报
回复

#ifndef __LOGGER_HPP__
#define __LOGGER_HPP__

/************************************************************************/
/* HEALER */
/************************************************************************/

#include <windows.h>


#include <map>
#include <string>
using namespace std;

class MultiThreadLock
{
public:
MultiThreadLock()
{
InitializeCriticalSection(&cs);
}

~MultiThreadLock()
{
DeleteCriticalSection(&cs);
}

void Lock()
{
EnterCriticalSection(&cs);
}

void Unlock()
{
LeaveCriticalSection(&cs);
}

private:
CRITICAL_SECTION cs;
};



class SingleThreadLock
{
public:
SingleThreadLock(){}
~SingleThreadLock(){}
void Lock(){}
void Unlock(){}
};




template<typename T, typename TM>
class Singleton
{
private:
typedef TM ThreadModel;
public:
Singleton()
{
}

~Singleton()
{
}

static T* Instance()
{
static ThreadModel _lock;
if (0 == _store())
{
_lock.Lock();
if (0 == _store())
{
T* pInst = new T();
_store() = pInst;
return _store();
}
_lock.Unlock();
}
return _store();

}


private:
static T*& _store()
{
static T* pInst = 0;
return pInst;
}
};



class _log
{
public:
_log(const char* fileName)
:m_hFile(INVALID_HANDLE_VALUE)
{
m_hFile = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);
}

~_log()
{
if (INVALID_HANDLE_VALUE != m_hFile)
{
CloseHandle(m_hFile);
}
}


public:
long Write(const char* msg)
{
DWORD dwWrite = 0;
if (INVALID_HANDLE_VALUE != m_hFile)
{
BOOL b = WriteFile(m_hFile, (void*)msg, (DWORD)strlen(msg), &dwWrite, NULL);
}

return dwWrite;

}

private:
HANDLE m_hFile;
};





class logger_manager
{
private:
friend class Singleton;

public:
_log* get_log_ptr(string const& name)
{
map<string, _log*>::iterator iter = map_.find(name);
if (map_.end() == iter)
{
_log* pLog = new _log(name.c_str());
map_[name] = pLog;
return pLog;
}
else
{
return (_log*)(iter->second);
}
}


private:
map<string, _log*> map_;
};


template<class TM>
class logger_helper
{
private:
typedef TM ThreadModel;
static void __do_log(string const& name, const char* msg)
{
static ThreadModel lock;
lock.Lock();
Singleton<logger_manager, TM>::Instance()->get_log_ptr(name)->Write(msg);
lock.Unlock();
}
public:

static void do_log(string const& name, const char* msg)
{
__do_log(name, msg);
}


static void do_log(string const& name, const wchar_t* msg)
{
DWORD dwLen = WideCharToMultiByte(GetACP(), 0, msg, -1, NULL, 0, NULL, NULL);
char* p = new char[dwLen];
WideCharToMultiByte(CP_ACP, 0, msg, dwLen, p, dwLen, NULL, NULL);
__do_log(name, p);
delete[] p;
}


static void do_log(string const& name, long msg)
{
char str[32] = { 0 };
itoa(msg, str, 10);
__do_log(name, str);
}

static void do_log(string const& name, long msg, bool hex)
{
if (hex)
{
char str[32] = { 0 };
itoa(msg, str + 2, 16);
str[0] = '0';
str[1] = 'x';
__do_log(name, str);
}
else
{
do_log(name, msg);
}
}

};


class LOG_DATE
{
};

class LOG_TIME
{
};

class LOG_ENDL
{
};

class LOG_HEX
{
public:
LOG_HEX(long a)
:a_(a)
{
}

operator int() { return a_; }
private:
long a_;
};

class LOG_BIN
{
public:
LOG_BIN(BYTE* b)
:b_(b)
{
}

BYTE* get() { return b_;}
private:
BYTE* b_;
};

class LOG_PROCESS_ID
{
};

class LOG_THREAD_ID
{
};


#define USE_LOGGER_YES 1
#define USE_LOGGER_NO 0


template<int, class>
class logger
{
};

template<class TM>
class logger<USE_LOGGER_YES, TM>
{
private:
typedef TM ThreadModel;

public:

logger(const char* name)
:name_(name)
{
}

logger& operator<<(const char* msg)
{
logger_helper<ThreadModel>::do_log(name_, msg);
return *this;
}

logger& operator<<(const wchar_t* msg)
{
logger_helper::do_log(name_, msg);
return *this;
}

logger& operator<<(long msg)
{
logger_helper<ThreadModel>::do_log(name_, msg);
return *this;
}


logger& operator<<(LOG_DATE)
{
SYSTEMTIME st;
GetSystemTime(&st);

char date[32] = { 0 };
sprintf(date, "%d/%d/%d", st.wMonth, st.wDay, st.wYear);
logger_helper<ThreadModel>::do_log(name_, date);
return *this;
}

logger& operator<<(LOG_TIME)
{
SYSTEMTIME st;
GetSystemTime(&st);

char time[32] = { 0 };
sprintf(time, "%d:%d:%d.%d", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
logger_helper<ThreadModel>::do_log(name_, time);
return *this;
}

logger& operator<<(LOG_ENDL)
{
logger_helper<ThreadModel>::do_log(name_, "\r\n");
return *this;
}


logger& operator<<(LOG_HEX hex)
{
logger_helper<ThreadModel>::do_log(name_, (int)hex, true);
return *this;
}


logger& operator<<(LOG_THREAD_ID)
{
DWORD dwThreadID = GetCurrentThreadId();
logger_helper<ThreadModel>::do_log(name_, dwThreadID);
return *this;
}

logger& operator<<(LOG_PROCESS_ID)
{
DWORD dwProcID = GetCurrentProcessId();
logger_helper::do_log(name_, dwProcID);
return *this;
}


protected:
void* operator new(size_t s);


private:
string name_;

};



template<class TM>
class logger<USE_LOGGER_NO, TM>
{
public:
logger(const char* name) { }

logger& operator<<(const char*) { return *this; }
logger& operator<<(const wchar_t*) { return *this; }
logger& operator<<(long) { return *this; }
logger& operator<<(LOG_DATE) { return *this; }
logger& operator<<(LOG_TIME) { return *this; }
logger& operator<<(LOG_ENDL) { return *this; }
logger& operator<<(LOG_HEX) { return *this; }

logger& operator<<(LOG_THREAD_ID) { return *this; }
logger& operator<<(LOG_PROCESS_ID) { return *this; }

protected:
void* operator new(size_t);

private:

};




#endif
georgeqp 2008-01-04
  • 打赏
  • 举报
回复
回1楼
一个很小的程序
懒得改代码了
所以找个懒办法
3楼的方法试过
有效
结贴
zdjray 2007-12-26
  • 打赏
  • 举报
回复
加上true参数
ustbsjl 2007-12-26
  • 打赏
  • 举报
回复
1楼正解
newflypig 2007-12-26
  • 打赏
  • 举报
回复
类FileOutputStream
的构造函数:
public FileOutputStream(String name,
boolean append)
throws FileNotFoundException

创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。
老紫竹 2007-12-26
  • 打赏
  • 举报
回复
xiebo1983 2007-12-26
  • 打赏
  • 举报
回复
可以先读出日志信息 然后加上新日志 再写到日志中去
hance1 2007-12-26
  • 打赏
  • 举报
回复
现在java的日志控件很多,为什么还要自己写呢。
log4j。

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧