Forum Moderators: coopster

Message Too Old, No Replies

Creating files logic problem

         

andrewsmd

4:54 pm on Oct 14, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here is my problem. I have a form with 3 inputs, a file path, start text and stop text. Now the user enters in all three we will say the file name is test.txt. This program is for creating multiple files out of one big one. For the sake of simplicity, lets say the contents of test.txt are
blah
blah
blah2
blah
blah
blah2
blah
blah
blah2
blah
blah
blah2
Now I want the user to be able to put in the start text blah and stop text blah2 and get files back like
test.txt1 contents being
blah
blah
blah2
test.txt2 contents being
blah
blah
blah2
test.txt3 contents being
blah
blah
blah2
and so on. I am having difficulty even coming up with logic for this. Does anyone have any suggestions? I am fairly familiar with all of the file commands so shoot away. Thanks,

cameraman

6:33 am on Oct 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You can use explode() [us.php.net] on the contents, looking for your stop text. With your example above it looks like you won't have anything that needs to be snipped out on the start text side, but if that could be the case - for example if start text is blah and stop text is blah2 and this situation is possible:
blah
blah
blah2
blah1 /* junk between stop and start */
blah3 /* junk between stop and start*/
blah
blah
blah2
blah
blah
blah2
blah
blah
blah2

Then just use explode again on each element of the array resulting from your first explode, this time looking for the start text.

robognome

6:55 am on Oct 15, 2008 (gmt 0)

10+ Year Member



you need a program, not a file command.

open firstfile for read
while not end of firstfile do the following:
1. while not starttext and not end of file keep reading
2. if starttext found do the following
a. open newfile // first file fo
b. while not endtext and not end of firstfile, read firstfile and write to newfile
c. close newfile
close firstfile
if endtext not found delete the last newfile created.

Probably buggy as a rain forest.

andrewsmd

1:36 pm on Oct 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I know I need a program I'm still working on it. The problem with your logic is, if the start text appears twice before the end text then it will end up creating two files. What I mean is if your file looks like this
blah
blah2
blah
blah
blah2
blah3
and your start text is blah and your end text is blah 3 you end up with a files like this
first file
blah
blah2
blah
blah
blah2
blah3
second file
blah
blah
blah2
blah3
third file
blah
blah2
blah3
and in my logic I want that to only be one file

cameraman

4:05 pm on Oct 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Using explode as I described above:

$content = file_get_contents($path);
$parts = explode($stoptext,$content);
$cnt = 1;
foreach($parts as $part) {
if(strpos($part,$starttext) !== 0) {
list($junk,$part) = explode($starttext,$part,2);
$part = $starttext . $part;
} // EndIf excise junk
$part .= $stoptext;
file_put_contents($path.$cnt++,$part);
} // EndForEach part

andrewsmd

4:52 pm on Oct 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks cameraman I got that working. The only problem I have is it is creating and extra file at the end. I don't really get the logic behind this so would you know why. This is the test data I'm using.
test.txt
blah
blah2
blah
blah2
test3
blahS
blah2
blahS
blah2
test3
blahf
blah2
blahf
blah2
test3

$content = file_get_contents("test.txt");

$stoptext = "test3";
$starttext = "blah";

$parts = explode($stoptext,$content);
$cnt = 1;

foreach($parts as $part) {

if(strpos($part,$starttext) !== 0) {

list($junk,$part) = explode($starttext,$part,2);

$part = $starttext . $part;

} // EndIf excise junk

$part .= $stoptext;

file_put_contents("test.txt".$cnt++,$part);

} // EndForEach part

cameraman

5:10 pm on Oct 15, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Using explode on stop text gives you an array, the first element being:
blah
blah2
blah
blah2

The second element is
blahS
blah2
blahS
blah2

The third element is
blahf
blah2
blahf
blah2

And the fourth element is empty because stoptext was at the end of the content.

Your second and third sections don't contain the start text - if that's a real condition and you don't want to include them, add:
if(strpos($part,$starttext) === false)
continue;

right after the foreach.
Let's say that the second section does have the start text, but not at the beginning:
blahS
blah
blah2
blahS
blah2

The second explode will produce an array with two elements:
blahS

and
blah2
blahS
blah2

list() puts the first element into $junk which we never use. The second element gets put back into $part.

If you're looking closely, you'll notice that explode "swallows" the delimiter, so we have to put it back into the content, hence the concatenation.

To eliminate the empty file at the end (or in any spot where the stop text is repeated with no content and no start text), enclose these two lines with an if:
if($part != '') {
$part .= $stoptext;
file_put_contents($path.$cnt++,$part);
} // EndIf section not empty
} // EndForEach part

andrewsmd

6:17 pm on Oct 16, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Ok well I just realized I can't use file_get_contents because I have a y offset input. What I mean is if the user enters the start text blah and a y offset of -1 and the file looks like this
foo
blah
bar
test3
since the -1 was entered we want to go back one line and grab that text. That was why I was putting the file into an array with the file() function. Any ideas?

andrewsmd

6:24 pm on Oct 16, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Alright finally got it. Thanks for all of your help here is the final code
$startKey is an array of positions where the start text appears in the contents array
the same with $stopKey only for the stop text

$content = file($filePath);

$startKey = array();
$stopKey = array();

if($_POST['startY'] == ""){

$startY = 0;

}//if startY

else{

$startY = intval($_POST['startY']);

}//else

if($_POST['stopY'] == ""){

$stopY = 0;

}//if stopY

else{

$stopY = intval($_POST['stopY']);

}//else

//store an array of start keys and
//stop keys. basically the startkey
//array has all of the keys of content
//where we need to start stored
//the same for the stopkey array
//except with the stop keys
foreach($content as $key => $i){

if((strpos($i, $startText)) !== false){

array_push($startKey, ($key + $startY));

}//if start text

if(strpos($i, $stopText) !== false){

array_push($stopKey, ($key + $stopY));

}//if

}//foreach

$fileCounter = 0;

//run everytime there is a start key position
//in the $contents array
foreach($startKey as $key2 => $j){

//this is the temp filename with the counter
$tempFileName = $filePath.$fileCounter;

//if the value of the start key is less
//than the value of the stop key then we need to write
//a file
if($j <= $stopKey[$fileCounter]){

//if the file has NOT been created
//we will run other wise the file
//exists meaning there were two
//start texts before the stop text
//this is how I get around
//doulbe start texts w/o creating
//extra files
if(!(is_file($tempFileName)) ){

for($temp = $j; $temp <= $stopKey[$fileCounter]; $temp++){

createFile($filePath, $content[$temp], $fileCounter);

}//while

}//if !

//else we need to increment the file name
else{

$fileCounter++;

}//else

}//if $j

}//foreach

}//startStop

echo("<p class = 'text'>$fileCount file(s) created.</p>");

function createFile($path, $data, $counter){

$newFile = ($path.$counter);

$f = fopen($newFile, 'a');

if(fwrite($f, $data));

else{

echo("<p class = 'text'>There was an error in writing the file: ".getFileName($newFile).". The file was not written.");
die();

}//else

}//createFile