tags:

views:

67

answers:

6

I want to delete a range of data from a text file using PHP. Let's assume the file contains the following:

Hello, World!

I want to delete everything from character 2 to character 7. The actual file I need to do this with is very large, so I don't want to have to read the large file in order to delete just a small, given range of data. The data contained within the given range is not known, so str_replace or preg_replace solutions wouldn't work anyways.

Thanks!

A: 

You don't want but you have to. Read and rewrite the whole file. That's why everyone would use a database for this, not a plain file

Col. Shrapnel
A: 

The simplest way I can think of is to read in the entire file as a string and use array_splice string_splice to remove a segment.

Edit:
Excuse me, I didn't mean array_splice, I meant string_splice, which is a custom function I made for my own use. It's something like this (I don't have it handy at the moment):

function string_splice($string, $start, $length, $replace) {
    $string = substr($string, 0, $start).$replace.substr($string,$length);
}

Edit:

This is NOT the ideal solution; please see the comments below. It's a bad idea to read a very large file into a string; in addition to memory consumption, operating on such a large string is very inefficient. A better solution is that proposed by gnud. Thanks.

Brian Lacy
Oh yeah for the large amount of data. Excellent. And using an *array* function to remove a *string* part is quite unusual ;)
Col. Shrapnel
For the love of god, he says the file is very large, and you suggest he read the entire thing into a string?
George Jempty
Geez, I said it was simple, I NEVER said it was a good idea. :P I highly recommend the database solution, *obviously*.
Brian Lacy
Mr Lacy, you need to learn what the purpose of SO is. When we pointed out that your answer was sub optimal for large files, we were helping the OP (original poster) that your solution was not appropriate for him. We did exactly what we were supposed to do. Sorry if this rubbed you the wrong way, but to then label us as "haters" just shows (IMO) how utterly mistaken you are about the purpose of SO. Its not to gain personal reputation, its to help the OP. I spent a point of my accrued personal rep to down-mod your answer. Kudos to you for leaving your original answer up.
George Jempty
Mr. Jempty, you're absolutely right. My original answer was sincere, but flawed; I'm afraid I reacted defensively to the negative feedback, when in fact it was accurate and well deserved. My apologies; I'll edit my answer to reflect this. I appreciate the tastefully appropriate and detailed reprimand.
Brian Lacy
+1  A: 

There is no way to remove a chunk in the middle of a file. You will need to read everything following the chunk to move it down to backfill the hole. Copying the relevant data to another file is an easy way to do this.

Ignacio Vazquez-Abrams
+2  A: 

If you for some reason have to use a file, and it's a big file, you can read in smaller chunks (like one line at the time), and write the data you want to keep out to a temporary file continously. This will cut down on memory requirements.

gnud
Dang, looks like I was too late on this one. :)
Brian Lacy
A: 

Here's a better solution than my original answer, although I'm still not sure it's ideal.

You could open the file for reading, and read in chunks, dropping whatever you read in into a second file which you've opened for writing. Then just skip the portion you're wanting to "delete".

Naturally at the end you'd copy your temp file over the original.

Edit:

Upon further reflection, I feel this is actually probably the most useful answer (unless/until someone has a better idea), but the credit must go to "gnud" for arriving at the same conclusion first.

Brian Lacy
A: 

I took your guys advice, plus I did some brainstorming, and I found a solution to my problem. Basically I took Ignacio's suggestion:

You will need to read everything following the chunk to move it down to backfill the hole. Copying the relevant data to another file is an easy way to do this.

But, instead of moving the data to a temporary file, I simply read each chunk and then immediately moved the file pointer backwards with fseek() and used fwrite() to fill in the hole. Then I truncated the file to the correct length with ftruncate().

Again, thanks everybody for the suggestions!

Evan Byrne