How to Create Binary Log File in Java using Log4J - java

I am able to create log files using FileAppender, RollingFileAppender,etc.,
My Problem is that the logs are written as plain text that anyone can read, but I want to register my logs as Binary Files that are not human readable.
Can anyone help me with the suggestion to create a Binary log file for an example code.

Its not such a good Idea to do what you wrote, but if you really need to, write an own appender like this:
package de.steamnet.loggingUtils;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class BinaryAppender extends AppenderSkeleton {
FileOutputStream fout;
public BinaryAppender() throws FileNotFoundException {
fout = new FileOutputStream("/tmp/somefile.log.bin");
}
#Override
protected void append(LoggingEvent le) {
String origMessage = le.getLoggerName() + " said: " + le.getMessage();
byte[] obscure = origMessage.getBytes();
for(int ii = 0; ii < obscure.length; ii++) {
if(obscure[ii] == Byte.MAX_VALUE) {
obscure[ii] = Byte.MIN_VALUE;
} else {
obscure[ii] = (byte)(obscure[ii] +1); // thats a really bad idea to create 'nonesense stuff' that way!
}
}
try {
fout.write(obscure);
} catch (IOException ex) {
System.out.println("too bad. File writer bombed.");
}
}
#Override
public boolean requiresLayout() {
return false; // we do all layouting in here.
}
#Override
public void close() {
try {
fout.close();
} catch (IOException ex) {
System.out.println("too bad. could not close it.");
}
}
}
Then in your log4j config use this class as appender and you are done with the writing part. for the reading part you again need to read it byte per byte and reduce the byte by one and then load a string from it.
Good luck.

I would use DataOutputStream BufferedOutputStream and FileOutputStream to write binary files. I assume you want the files to be machine readable rather than non-readable. ;)
Log4j is designed for text files, however you can use its logging levels like.
private static final Log LOG =
static DataOutputStream out = ... FileOutputStream ...
if(LOG.isDebugEnabled()) {
// write a debug log to out
}

Related

Java how to create, open, write, and read then close the file

so here's the problem,
i stack on how to create, open, write, and read file, with this code
import java.util.*;
import java.io.*;
class class_Name{
Formatter x; // Variable: creating new file
File file = new File("file.txt"); // Variable: check file existence
//creating txt file
public void creating_file(){
try{
x = new Formatter("file.txt");
}catch(Exception e){
System.out.println("you got an error");
}
}
public int check_file(){
if(file.exists()){
return 1; // in main method, check if file already exists just pass from creating file
}else{
return 0; // in main method if return value 0, then it create new file with "public void creating_file()" method
}
}
so the problem is when i tried to write something in the file, i using class Formatter and it always format all the text data that in it before and class Formatter won't work if public int check_file() is equals to 1 because it skip from creating file using Formatter class and can't just write in the file because variable x undefined
this is the code how i write text in a file
public void recording_to_file(){
x.format(format, args);
}
and to closing file i need to handle error like this
public void close_file(){
try{
x.close();
}catch(Exception e){
file.close();
}
}
}
there was just ton of class that i need to do something with just one file, or maybe there was one simple class that can do all in one like(write, open, read, close), i am new in java, i think maybe in here i can get help, thank you
Take a look at this.
The second argument to the FileWriter costructor (true) tells it to only append data, instead of overwriting any.
import java.util.*;
import java.io.*;
class SomeClass{
Formatter x;
File file = new File("file.txt");
public void creating_file(){
try{
x = new Formatter(new FileWriter(file, true));
}catch(Exception e){
System.out.println("you got an error");
}
}
public boolean check_file(){
return file.exists();
}
}

Type full width colon (:) to setProperty in Java

I'm trying to set my database property, so in the future users could change it if they want to change the route of the database. The problem is when I try to set something with full width colon, which always add a backslash escape character .
I've tried normal and double escape, but it doesn't work.
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
public class SetProps {
public static void SetDefaultProps(){
Properties prop = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream("./build/classes/configuracion.properties");
// Set the database property
prop.setProperty("url", "jdbc:mysql://192.168.1.192:3306/ordenestaller");
// Save Properties
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
SetDefaultProps();
}
}
Hardcoding the db url in the java code is not a good coding practice.
I would recommend you to put those urls in a properties files and read them as and when required using a ResouceBundle.
you can have "information.properties" file somewhere in your classpath and the contents of that file can be
dbURL:jdbc:mysql://192.168.1.192:3306/ordenestaller
and now in your code you can get this using a ResourceBundle
ResourceBundle bundle = ResourceBundle.getBundle("information");
String dbURL= bundle.getString("dbURL");
This will have an added advantage that you will not need to recompile your java class again if DB URl is changed.
Hope it helps

Add support to UTF-8 chars without writing all class code from 0? [Bukkit and Java]

I have 3 class to handle all configs. (2000 lines in 2 class)
And I want add support to UTF-8 chars without writing all code from 0 ;/
I show my smallest class (is not finished and I don't want to spam with 1400 lines :))
Have actual only two variables:
package com.gmail.bukkitSmerf.professionalWarns;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
public class LangHandler {
private static String lWarns_DeletedWarnAddon, lWarns_ExpiredWarnAddon;
public static String getlWarns_DeletedWarnAddon() {
return lWarns_DeletedWarnAddon;
}
public static String getlWarns_ExpiredWarnAddon() {
return lWarns_ExpiredWarnAddon;
}
public void createConfig(boolean forceConfigUpdate) {
try {
String langFileName = "languageEN.yml";
InputStream input = ProfessionalWarns
.getPluginResource_languageEN();
if (ConfigHandler.getcGeneral_Language().equalsIgnoreCase("PL")) {
langFileName = "languagePL.yml";
input = ProfessionalWarns.getPluginResource_languagePL();
}
File langFile = new File(ProfessionalWarns.getPluginDataFolder(),
langFileName);
if (!langFile.exists()) {
langFile.getParentFile().mkdirs();
ConfigHandler.copy(input, langFile);
}
YamlConfiguration lang = new YamlConfiguration();
FileConfiguration rawLang = YamlConfiguration
.loadConfiguration(input);
lang.load(langFile);
lWarns_DeletedWarnAddon = lang.getString("Warns.DeletedWarnAddon",
rawLang.getString("Warns.DeletedWarnAddon"));
lWarns_ExpiredWarnAddon = lang.getString("Warns.ExpiredWarnAddon",
rawLang.getString("Warns.ExpiredWarnAddon"));
if (ConfigHandler.iscGeneral_AutoUpdateConfigs()
|| forceConfigUpdate) {
FileWriter fw = new FileWriter(langFile);
PrintWriter pw = new PrintWriter(fw);
pw.flush();
pw.write("Warns:\n DeletedWarnAddon: '"
+ lWarns_DeletedWarnAddon + "'\n ExpiredWarnAddon: '"
+ lWarns_ExpiredWarnAddon + "'");
pw.close();
}
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
ProfessionalWarns
.logWarning("Error when trying create/write/reload language file!");
}
}
}
I don't have idea how to use that UTF-8 here.
I also don't want delete any features.
If you can, give me also some advices about that code :)
//Sorry for my English
Based on your comment, I'm going to blame your use of FileWriter:
FileWriter fw = new FileWriter(langFile);
This relies on your installation's default encoding, which I'm willing to bet is not UTF-8. You can verify this with the following:
System.out.println(Charset.defaultCharset());
Regardless, the correct way to write UTF-8 characters to a file is to use an OutputStreamWriter:
FileOutputStream fos = new FileOutputStream("your_file");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
PrintWriter pw = new PrintWriter(osw);
And unless this is one-off code, you should close the FileOutputStream in a finally block.

java write class to file

This is for a homework I'm doing on my walk learning java.
I'm writing a program and it is all working as expected except the read/write to file.
I have one class named Medico that holds only one string (typeOfMedico) and one int (valorFacturado). Medico is a sub class of Pessoa. Pessoa holds data like name and address. public class Medico extends Pessoa implements Serializable is the main function on Medicoclass.
On my main class, named Clinica, I ask for user input and at the end of I create a new Medico that its added to an Arraylist named medico.
For reading and writing to file I've created this class:
package clinica;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class FicheiroObjectos {
private ObjectInputStream iS;
private ObjectOutputStream oS;
public void abreLeitura(String nomeDoFicheiro) throws IOException {
iS = new ObjectInputStream(new FileInputStream(nomeDoFicheiro));
}
public void abreEscrita(String nomeDoFicheiro) throws IOException {
oS = new ObjectOutputStream(new FileOutputStream(nomeDoFicheiro));
}
public Object leObjecto() throws IOException, ClassNotFoundException {
return iS.readObject();
}
public void escreveObjecto(Object o) throws IOException {
oS.writeObject(o);
}
public void fechaLeitura() throws IOException {
iS.close();
}
public void fechaEscrita() throws IOException {
oS.close();
}
public void leFicheiroMedicos() {
Medico medicos;
while (true) {
try {
medicos = (Medico) this.leObjecto();
Clinica.medicos.add(medicos);
} catch (EOFException eof) {
break;
} catch (ClassNotFoundException cnf) {
System.out.print("\nClassNotFoundException!\nO programa vai terminar\n");
System.exit(-1);
} catch (IOException ioe) {
System.out.print("\nErro ao ler o ficheiro!\nO programa vai terminar\n");
System.exit(-1);
}
}
}
public void escreveFicheiroMedicos() {
try {
for (Medico medicos: Clinica.medicos) {
this.escreveObjecto(medicos);
}
} catch (IOException e) {
System.out.print("\nErro ao escrever no ficheiro!\nO programa vai terminar\n");
System.exit(-1);
}
}
}
On my main class I've created this two functions:
public static void insereDadosExistentes() {
try {
FicheiroObjectos file = new FicheiroObjectos();
file.abreLeitura("Medicos.dat");
file.leFicheiroMedicos();
file.fechaLeitura();
} catch (IOException ioe) {
}
}
public static void gravarMedicos() {
try {
FicheiroObjectos file = new FicheiroObjectos();
file.abreEscrita("Medicos.dat");
file.escreveFicheiroMedicos();
file.fechaEscrita();
} catch (IOException e) {
System.out.print("\nErro ao escrever no ficheiro!\nO programa vai terminar\n");
System.exit(-1);
}
}
}
Then added insereDadosExistentes() at the beginning of my mainfunction and added gravarMedicos() just after adding a Medico to my medicos arraylist.
When I run my program (On the first run, file Medicos.dat, does not exist) and create a Medico, Medico is added to my arraylist and the file Medicos.dat is created. Then I stop the program and on the next run, which now haves a Medicos.dat file, I get the error:
Erro ao ler o ficheiro!
O programa vai terminar
The problem is in writing the file or reading the file?
I know the error is given when reading the file but it could be because the writhing to file is not properly executed.
If I try to open Medicos.dat I can see some characters but nothing related with the info I input so I don't even know if the file writing is ok.
Remember that all besides file handling is working as expected.
Can you point me In some directions?
favolas
Make sure that you explicitly close the ObjectOutputStream so that all the data is written.
Your problem is an IOException. However, the backtrace will tell you what's going on: trouble opening, reading, what? you can call printStackTrace(), but better you can use a debugging and just look at the stack trace.
If you catch an exception dont just write something to system.out but print the stacktrace this will usually give you a clue whats wrong
try {
FicheiroObjectos file = new FicheiroObjectos();
file.abreEscrita("Medicos.dat");
file.escreveFicheiroMedicos();
file.fechaEscrita();
} catch (IOException e) {
e.printStackTrace();
}
Q: Are you trying to read and write DATA, or are you trying to serialize and deserialize OBJECTS?
I think all you need to do is open and write to a simple text file:
For example:
http://www.exampledepot.com/egs/java.io/AppendToFile.html
import java.io.*;
public class TestFile
{
public static void main (String[] args)
{
// Test "append"
// SOURCE: http://www.exampledepot.com/egs/java.io/AppendToFile.html
try {
BufferedWriter out =
new BufferedWriter(
new FileWriter("myfile.txt", true));
out.write("testing: a b c\n");
out.write("testing: d e f\n");
out.close();
}
catch (IOException e) {
}
}
}
Sample output:
testing: a b c
testing: d e f
I don't know Java's serialization stuff at all, but this seems "too easy":
public void escreveObjecto(Object o) throws IOException {
oS.writeObject(o);
}
How is the object output stream supposed to know what portions of your object needs to be written to disk? Could be that your object contains nothing but computed values that shouldn't be stored. Could be that your object's data needs to be stored completely. Perhaps references to String objects should just be dropped... or perhaps those Strings should be written to disk.
There must be more to using the ObjectStream stuff than you're showing here -- and paulsm4's answer shows how writing your own content by hand isn't too bad. Should you be taking that approach instead? Does your class have a defined storage format that you must adhere to?

JLayer Synchronization

(I'm attempting to make my previous question more generic in the hopes of a solution.)
I am using the JLayer library and a sample.mp3 file. I would like to play AND decode the file at the same time.
However, I want them to be synchronized - if a part of the song is decoded, it is also played. Nothing is decoded before it is played and vice versa (to a reasonable degree, of course).
Here is how a song is played and decoded, respectfully:
Player p = new Player(InputStream mp3stream);
p.play();
Decoder d = new Decoder();
BitStream bs = new Bitstream(InputStream mp3stream);
SampleBuffer s = (SampleBuffer) d.decodeFrame(bs.readFrame(), bs);
// ... for processing the SampleBuffer but irrelevant for the question
I currently use:
InputStream mp3stream = new FileInputStream("sample.mp3");
but this uses the whole song at once so I am unable to synchronize. Is there a way to break the sample.mp3 into pieces that can be manipulated by both processes? If I had small enough pieces I could run both pieces into the processes, wait until both finished, and then grab the next small piece and repeat until I was out of small pieces.
Note: I have tried using ByteArrayInputStream with no success - but perhaps my methodology is incorrect when using it.
I hope i get this right:
You have a single input file
You want that two different input streams are synchronized in the sense, that "they must make the same progress" in the stream.
This is an interestig question. I came up with the following sketch (compiles, but didn't execute it, so you may do a little testing first).
Create a wrapper object "StreamSynchronizer" that controls access to the underlying input. Only a single byte is read until all derived streams have read this byte.
Derive any number of "SynchronizedStream" instances from this that delegate the "read" back t the StreamSynchronizer.
package de.mit.stackoverflow;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class StreamSynchronizer {
final private InputStream inputStream;
private List activeStreams = new ArrayList();
private int lastByte;
private Set waitingStreams = new HashSet();
private Object lock = new Object();
public StreamSynchronizer(InputStream is) throws IOException {
super();
this.inputStream = is;
lastByte = getInputStream().read();
}
public void close(SynchronizedStream stream) {
activeStreams.remove(stream);
}
public SynchronizedStream createStream() {
SynchronizedStream stream = new SynchronizedStream(this);
activeStreams.add(stream);
return stream;
}
public InputStream getInputStream() {
return inputStream;
}
public int read(SynchronizedStream stream) throws IOException {
synchronized (lock) {
while (waitingStreams.contains(stream)) {
if (waitingStreams.size() == activeStreams.size()) {
waitingStreams.clear();
lastByte = getInputStream().read();
lock.notifyAll();
} else {
try {
lock.wait();
} catch (InterruptedException e) {
throw new IOException(e);
}
}
}
waitingStreams.add(stream);
return lastByte;
}
}
}
package de.mit.stackoverflow;
import java.io.IOException;
import java.io.InputStream;
public class SynchronizedStream extends InputStream {
final private StreamSynchronizer synchronizer;
protected SynchronizedStream(StreamSynchronizer synchronizer) {
this.synchronizer = synchronizer;
}
#Override
public void close() throws IOException {
getSynchronizer().close(this);
}
public StreamSynchronizer getSynchronizer() {
return synchronizer;
}
#Override
public int read() throws IOException {
return getSynchronizer().read(this);
}
}

Categories