-1

So I have this file:

randomline
ernegvggvdr
dsvdfssvdsv
dfsfvfvs
svdfsdfdfs
dfsfvfv
dsvvsvvfggd

This goes on for thousands and thousands of lines. In fact, it's about 45 thousand lines.

I'd like to read the first 100 lines and delete them.

So I know that the following code reads everything in a file:

Files.readAllBytes(new File(new File("").getAbsolutePath() + "lines.txt").toPath());

I also know that the following code deletes the whole file:

new File(new File("").getAbsolutePath() + "line.txt").delete();

Then maybe re-create an empty one with this:

new File(new File("").getAbsolutePath() + "line.txt").createNewFile();

But all of these apply to the entire file as opposed to the first X lines.

Shark
  • 23
  • 4
  • Files are sequential. You can't just delete lines at the beginning of a file. What you can do is 1. read the file line by line. 2. do nothing with the first 100 read lines. 3. Write the remaining lines to another file. 4. delete the original file. 5. rename the created file to the original name. Read the Java IO tutorial: http://docs.oracle.com/javase/tutorial/essential/io/charstreams.html – JB Nizet Sep 27 '14 at 17:10
  • `new File("").getAbsolutePath() + "line.txt"` ... pretty funny and not because you forgot a file separator. Use `new File("line.txt").getAbsolutePath()` instead. – Tom Sep 27 '14 at 17:17
  • @JarrodRoberson the “duplicate” question is about C# and has no accepted answer. (And the two answers it has are not really helpful, imho.) So I'm not sure whether this will answer the OP's question. – 5gon12eder Sep 27 '14 at 17:40
  • I apparently pasted the wrong link by accident. –  Sep 27 '14 at 19:52

2 Answers2

0

Think of a file as a one-dimensional array of bytes. You cannot simply delete something from the beginning. Instead, you'll need to fill up the gap by copying over the data. In addition, a file itself is completely unstructured. It doesn't “know” it has lines of text. It is purely convention the after each \n character, we say a new line begins.

If you want to convert this file:

the first line
the second line
the third line
the fourth line
the fifth line

which actually looks like

{'t', 'h', 'e', ' ', 'f', 'i', 'r', 's', 't', ' ', 'l', 'i', 'n', 'e', '\n', 't', 'h', 'e', ' ', 's', 'e', 'c', 'o', 'n', 'd', ' ', 'l', 'i', 'n', 'e', '\n', 't', 'h', 'e', ' ', 't', 'h', 'i', 'r', 'd', ' ', 'l', 'i', 'n', 'e', '\n', 't', 'h', 'e', ' ', 'f', 'o', 'u', 'r', 't', 'h', ' ', 'l', 'i', 'n', 'e', '\n', 't', 'h', 'e', ' ', 'f', 'i', 'f', 't', 'h', ' ', 'l', 'i', 'n', 'e', '\n'}

into that file:

the third line
the fourth line
the fifth line

which actually looks like

{'t', 'h', 'e', ' ', 't', 'h', 'i', 'r', 'd', ' ', 'l', 'i', 'n', 'e', '\n', 't', 'h', 'e', ' ', 'f', 'o', 'u', 'r', 't', 'h', ' ', 'l', 'i', 'n', 'e', '\n', 't', 'h', 'e', ' ', 'f', 'i', 'f', 't', 'h', ' ', 'l', 'i', 'n', 'e', '\n'}

You'll need to figure out up to which byte (in this case the 31st) to skip and then shift all remaining bytes by that amount toward the beginning. This can be done efficiently in Java using memory mapped files (see FileChannel) but it is not a trivial task.

Instead, you should probably process the file as a stream and write it to another file. Then, eventually, you can rename the new file to overwrite the old one. If you have enough disk space (And you have it, don't you?), this is the easiest way to go.

  • Open the input file and create a BufferedReader for it.
  • Open the output file.
  • Repeat for the first n lines in the input:
    • Do nothing.
  • Repeat for all remaining lines in the input:
    • Write the line to the output file.
  • Close both files.
5gon12eder
  • 24,280
  • 5
  • 45
  • 92
-1

If this is your whole problem, Java is not the best way - you can do this easily with UNIX utilities like head and tail.

What's the opposite of head? I want all but the first N lines of a file

To read and write text files line by line in Java, you need to learn about BufferedReader, PrintWriter etc.

Community
  • 1
  • 1
wrschneider
  • 17,913
  • 16
  • 96
  • 176