Solved

append to begining of file

Posted on 2004-08-04
44
1,295 Views
Last Modified: 2010-05-18
Hi,

Is there any easy way I can append a string to the begining of a file ? I know a coupla ways but not happy with them..

1. I can read the entire file and then create a new file but this time inserting a new string at the begining. This is not a good soln bcos the file is a huge log.

2. Using RandomAccessFile, I can insert at the begining but it rather does a replace than an insert.

appreciate any suggestions,

cheers,
0
Comment
Question by:sands76
  • 13
  • 12
  • 9
  • +4
44 Comments
 
LVL 12

Expert Comment

by:Giant2
ID: 11715427
create a new temporary file over you write the startString and append the resta of the oldFile.
Then copy the temporary file in the oldFile.

(It's an old solution, but it goes)

Bye, Giant.
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11715432
1) write the new lines to a new file
2) append the lines from the old file one by one to this new file
3) delete the old file
4) rename the new file
0
 
LVL 12

Expert Comment

by:Giant2
ID: 11715452
TimYates, as I told before.
;-)
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11715534
;-)  hehehe
0
 
LVL 1

Expert Comment

by:wolfc
ID: 11715552
If it is possible within your application, reverse read the file.
0
 
LVL 1

Author Comment

by:sands76
ID: 11715720
hi,

But isnt this somewhat similar to what I  posted in my question ?

"2) append the lines from the old file one by one to this new file" , would involve reading the entire file and writing its contents to a new file which is exactly what I want to avoid..

The log file size could be anywhere between 30- 70 Mb ! hard to believe there is no cost efficient method to insert a line at the top in java :(
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11715761
> hard to believe there is no cost efficient method to insert a line at the top in java :(

Or any programming language...  It's du to the way files are stored on disk, so it's not just java...

As wolfc says, can't you store the file in reverse?

Do you need to add to the top of the file AND the bottom of it?
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11715764
> But isnt this somewhat similar to what I  posted in my question ?

It's the only way of doing it...you had guessed right...
0
 
LVL 1

Expert Comment

by:wolfc
ID: 11715879
I meant just insert new strings at the end of the file, and when it comes to reading the file start at the bottom.
0
 
LVL 12

Expert Comment

by:Giant2
ID: 11715905
>when it comes to reading the file start at the bottom

It's an idea, but if I want to add a String at the end? In this manner I have the same problem as now.

:-)
0
 
LVL 1

Author Comment

by:sands76
ID: 11715925
Nope.. cant store the file in reverse.. and gotta add the line only at the top.

a brief on why I need to do this:

I am using log4j for logging purposes with the DailyRollingFileAppender which creates a log daily. I am having the log saved as xpto.csv which later is imported to diff applications. Each .csv file should have a line at the top with the column headings.

What is your opinion would be the load reading and writing a 70 Mb file ?

any other workaround ??


thnx,
0
 
LVL 12

Assisted Solution

by:Giant2
Giant2 earned 90 total points
ID: 11715945
You could prepare this column heading before to start to write on this file.
0
 
LVL 1

Expert Comment

by:wolfc
ID: 11715956
Just 1 line each day in a 70 MB file?
Create temp, write header, append file, rename temp.
Points for Giant2 and TimYates.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 11716034
>>Each .csv file should have a line at the top with the column headings

But why would logging cause that line to disappear such that it needs reinserting?
0
 
LVL 1

Author Comment

by:sands76
ID: 11716202
At midnight every day, the logger creates a new log and renames the earlier log as xpto-04-08-2004.log.

I havent yet found a way to make the logger insert a line when generating a new log. I want to insert this line manually for later requirements..

thnx
0
 
LVL 1

Expert Comment

by:wolfc
ID: 11716322
In Log4j the layout associated with the appender allows for a header. It depends on which layout you're using.
DailyRollingFileAppender will then start with the header.
0
 
LVL 1

Author Comment

by:sands76
ID: 11716520
wolfc,

U might yet turn out to be my saviour! I am currently focussing on the appender layout but meanwhile If u can suggest anything, would appreciate a lot. My log4j.properties look like this:

log4j.appender.R2.layout=org.apache.log4j.PatternLayout
log4j.appender.R2.layout.ConversionPattern=%m%n

My admin informed me that the log file could cross more than 150 Mb everyday..:( it just seems that reading and writing the file is not an option...

thnx

p.s: I hv tried to increase points before, but cud never do it.. How do I go about it ?? the New point value box has the points i want to increase..
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11716665
> I hv tried to increase points before, but cud never do it.. How do I go about it ??

Type the new amount of points into the points box, and post a comment :-)
0
 
LVL 1

Author Comment

by:sands76
ID: 11716728
cmt
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11716766
that's how it should work anyway... :-/
0
 
LVL 1

Author Comment

by:sands76
ID: 11716891
well.. its not !

What bout the resource consumption in reading and writing a 100 Mb log file? any opinions ?
0
 
LVL 13

Expert Comment

by:Webstorm
ID: 11717259
Hi all,

A solution is to use low level I/O operations (impossible in Java without platform dependent native code) to replace disk cluster by disk cluter to shift the file content. It will take the same time as other solutions, but take less disk space.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Expert Comment

by:sri_prasanth
ID: 11717673
I think the best idea is to append while creatin a new file......as said by many
But is this a compulsion that u keep it in the beginning???
u can keep it at the end of the file n when ever u require these names u can just go to the end, read the column headings from backwards (u can as they are static) and do wht u want???????
0
 
LVL 1

Author Comment

by:sands76
ID: 11717917
Unfortunately, it has to be at the beginning. As I said before, I have to dump the files at a particular location from where its picked by other processes over which I have no control.  

My specification says it has to be delivered in this format..
0
 
LVL 1

Expert Comment

by:wolfc
ID: 11718180
It would require some programming (PatternLayout does not support header).

Extend PatternLayout, add String layout field with getter & setter, use the new layout in log4.

log4j.appender.R2.layout=nl.wolfc.log4j.HeadedPatternLayout
log4j.appender.R2.layout.Header=a;b;c
0
 
LVL 1

Author Comment

by:sands76
ID: 11718390
thnx wolfc, will keep working on it.. Meanwhile, heres my code for creating a new file with a line and later appending to it.. seem to be doing something wrong because its not functioning well and the inserted line is being overwritten:

   public static void copy(String source_name, String dest_name)
   throws IOException
   {
                       File source_file = new File(source_name);
                       File destination_file = new File(dest_name);
     
                       FileInputStream source = null;
                       FileOutputStream destination = null;
                       byte[] buffer;
                       int bytes_read;
                                         
                       try {
 
              BufferedWriter out = new BufferedWriter(new FileWriter(destination_file.getAbsolutePath(), true));
            out.write("My STRING");
            out.close();            

                                                source = new FileInputStream(source_file);
                                                destination = new FileOutputStream(destination_file);
                                                buffer = new byte[1024];
                                                while(true) {
                                                    bytes_read = source.read(buffer);
                                                    if (bytes_read == -1) break;
                                                    destination.write(buffer, 0, bytes_read);
                                                }
                                            }
}

thnx
0
 
LVL 35

Accepted Solution

by:
TimYates earned 100 total points
ID: 11718625
                                               destination = new FileOutputStream(destination_file, true);
0
 
LVL 1

Expert Comment

by:wolfc
ID: 11719279
Better yet, don't close the BufferedWriter and use a BufferedReader(FileReader) for the source.
0
 
LVL 12

Expert Comment

by:Giant2
ID: 11723640
I told:
>You could prepare this column heading before to start to write on this file.

If you don't know the column heading you can write a line empty.
After the end of the writing all the file, access in Random mode, so you can overwrite this first line without read the full file.

Bye, Giant.
0
 
LVL 1

Expert Comment

by:wolfc
ID: 11723966
Giant: The writing of an (empty) line into the file would require an extension of Log4j layout.
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11724060
>  Giant: The writing of an (empty) line into the file would require an extension of Log4j layout.

Agreed, and you might as well just add the header in, as wolfc said :-)
0
 
LVL 1

Author Comment

by:sands76
ID: 11724362
Hey Guys!

Appears I hv almost found a breathrough..

1. the File copy code I posted above is working great now (thnx TimYates for correcting the bug)

BUT

I have found a better way to achieve my task (thnx to Giant and wolfc)

IT is possible to insert a blank line at the top of LOG.. very simple actually. Just inserting a "%n" in the ConversionPattern does this for me. Now, I am accessing the file using RandomAccessFile to write my string  but am running into a small problem (i hope!).

Whats happening is that , RAF is writing my string ok to the first blank line but is eating away part of my data in the second line!!! whys this happening ??

Heres my RAF code:

    RandomAccessFile raf = new RandomAccessFile(nm,"rw");
        raf.seek(0);
        raf.writeBytes("USER;ACTION;DIALOG");
//        raf.writeBytes("\n"); // inserting this line is not helping anyway...
        raf.close();

My original file:

                                        // <- this is the blank line
sands;testing;cude;munde
sands;testing;cude;munde

My RAF modified file : as u can c some data is missing...

USER      ACTION      DIALOG      
e      munde            
sands      testing      cude      munde


What am i doing wrong !?
thnx,
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11724410
It won't work...  you have to add (anstead of a blank line) the same number of spaces as you will need for the header (like 80 of them or something if that's enough)

The RandomAccessFile is just writing over the chars at the start of your file, so it writes over the newline char, then over your data...

So you need to insert spaces that you will replace at a later date :-)

If you do it that way ;-)
0
 
LVL 12

Expert Comment

by:Giant2
ID: 11724433
So, what I suggest is not really wrong:
>If you don't know the column heading you can write a line empty.
>After the end of the writing all the file, access in Random mode, so you can overwrite this first line without read the full file.

0
 
LVL 1

Author Comment

by:sands76
ID: 11724464
hmm.. cant get it right.. can u pl correct my code and post it ?

thnx
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11724480
> Just inserting a "%n" in the ConversionPattern does this for me.

You need loads of spaces, then %n

I think
0
 
LVL 12

Expert Comment

by:Giant2
ID: 11724508
because:
_________________________________\n
1st data
2nd data

when you write the first line (hallo!) you have:
hallo!_____________________________\n
1st data
2nd data

so, inserting more spaces before \n, the seek & overwrite the first line overwrite these blank spaces.
0
 
LVL 1

Author Comment

by:sands76
ID: 11724513
yeah..got it right away.. :9

but something doesnt make sense.. To insert a string "USER;ACTION;DIALOG" , I need to add 10 %n in my config file.

But why 10 ? how is this deciphered ? well, I am ecstatic that I could achieve what I wanted but sure would help if I understood what I am doing !

thnx!

P.S: I want to increase some points on this one and split them.. but hv never been able to do it.. any gauranteed way to increase the points !!? Right now the New Point Value box has a value 100 in it.. So, when I clik submit, it shud raise the points right !!!?
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11724525
this question is already worth 100, so you'd have to type a bigger number :-)
0
 
LVL 12

Expert Comment

by:Giant2
ID: 11724558
"USER;ACTION;DIALOG" are 18 chars.
But they are formatted (using the ";"), so the size you must deserve changes.
0
 
LVL 1

Author Comment

by:sands76
ID: 11724575
I got that part but still unable to comprehend how 18 chars translates to 10 new lines ? The thing is if I alter the string (make it longer), I will hv to keep inserting and removing %n untill I hit the correct number!

i imagine the soln is not guess work !! :)

p.s: i hv increased the points. hope it works now..
0
 
LVL 35

Expert Comment

by:TimYates
ID: 11724612
newline is probably;

   "\n\r"

So 10 new lines is 20 chars, which is 18 chars for your header, and two for the newline at the end of it :-)

Tim
0
 
LVL 1

Author Comment

by:sands76
ID: 11724667
thnx guys.. over and out
0
 
LVL 12

Expert Comment

by:Giant2
ID: 11725275
:)
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This video teaches viewers about errors in exception handling.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now