Jump to content

Recommended Posts

I created a class which should creates new binary file (called 4.ip) in the case that the file does not exist. Method reset() does the job. Then I try to add some numbers from Ip to the file. I try to use binary mode but It looks like it corrupts the file. First value 0E is written correctly. I have marked the BOM which was created in the reset method (idk if is this right when it should be binary file.

 

2ngezbk.jpg

 

To see the above, uncomment the die(); on line 413. Then to see the bellow, comment it back.

 

When I try to write the second value (line 415), the file looks corrupted, and all the 0000 disappear.

 

242id81.jpg

 

This is the source code:

http://paste.ofcode.org/v8M4DwrH7hQzkJMEDjaRpt

please see the lines 412-418.

<?php
include("scan_ips_class.php");
$scanIPs = new Scan_ips;
?>

Please help because I really cannot find out solution, and I am lost. Trying to solve this few days.

Link to comment
https://forums.phpfreaks.com/topic/284681-binary-fwrite-in-mode-rb/
Share on other sites

Yet I show you working version which is simplified. This uses no class:

http://paste.ofcode.org/8ipwC6eWGPxZpHGK5DQFmg

so you can see how it works. The written data do not corrupt the file. But why I cannot use the class to do that?

Edited by murfy

Your code does not generate the BOM mark when I try it, and I see no reason why it should. I'd suspect you are somehow modifying the file after the fact, such as by opening it in an editor that automatically adds the BOM.

 

on a side note, your loop in the reset method could be simplified into

$t = str_repeat(chr(0), $this->bufferSize);

Your code does not generate the BOM mark when I try it, and I see no reason why it should. I'd suspect you are somehow modifying the file after the fact, such as by opening it in an editor that automatically adds the BOM.

 

on a side note, your loop in the reset method could be simplified into

$t = str_repeat(chr(0), $this->bufferSize);

 

Thanks for this piece of code, can be useful. But did you see the file to be corrupted or not? Can you find the reason why it corrupts? In recent post I have added the second version, which is working, so I would like to know if you noticed same problem like me.

Are you talking about the BOM mark being the corruption, or the fact that all your null characters disappear? I may have mis-understood your initial post.

 

fwiw, the comments over on devshed about this being a fairly dumb thing to do just to store a list if IPs are accurate. With your fairly limited list of IP's you could just store them one per line or similar and be done with it without having to futz around with all this binary reading/writing/seeking etc. Your code would be drastically simplified and perform just as well.

1) I don't know if the BOM mark is a corruption when it is there in binary file. I have no idea how it was generated.

2) When the BOM mark disapears it could be taken as a corruption of BOM mark

3) Yes, the 0000 data disapear till the end of file, so this is corruption too

 

I wanted to do it binary to gain a speedy approach. The first write to this file should have about 120-140 IPs and then just adding few IPs per minute would be nice. I know I could simply add it to txt file, but then when I would want to make sure that the IP is not in the list I would need to search whole file if it contains the IP. Why do you think that simple file solution would be better performance?

 

This is ideal I think, I just jump to one segment to check if some IP is there. In the moment I have working class but it writes only 3 bytes of the first IP, and the next IP corrupts the file, so I want to find the cause today. Hopefully I will solve it today. Do you think that file seeking is slower because it is on hard drive than search in heap which is in RAM?

Also, can you help with this? I found that when I write a byte it uses two bytes instead one:

 

so the number 64 should be correctly in the blue circle. There should be 7864 5E3C

because here I have inserted 4 numbers: 120, 100 and 94, 60. So the result is like it uses Unicode because ot the unicode BOM which is on the begin of file. How should I create the file without the BOM, to have standard binary file behaviour? This is strange. I created the file with xb option and then added the string like this:

fwrite($fh,$t);

Yet I did a check of length

die(strlen($t)."");  // 750*254=190500 is OK.

This looks like the buffer size is correct but still, why it is written in wrong way?
 

 

av1xqv.jpg

Edited by murfy

Why do you think that simple file solution would be better performance?

I didn't say it'd have better performance, I said it'd probably be just as good (though it may be better). In any event the performance difference between your messy binary system and a plain text system is probably so minor that it's not even worth mentioning. A plain text system would be far easier to code however and much more readable.

 

You could make things even simpler by letting PHP do a lot of the work and just used a stored array and include(). I've done this for a number of small lists or configuration files:

function checkIP($ip){
   $ipList = include('ips.php');
   return in_array($ip, $ipList);
}

function addIP($ip){
   if (checkIP($ip)) return;
   
   $ipList = include('ips.php');
   $ipList[] = $ip;
   
   file_put_contents('ips.php', '<?php return '.var_export($ipList, true).';');
}
See how much simpler that code is?

Of sure your solution is simple and I also use it for different things. But it's true that I did not do any real site for real traffic using RS. I would like to do one site with RS and use there the IP container. But because IP list is demanded to be offten readed and offen searched for exact item (comparison two items) so I thought it could be good idea. It is not problem to me to make the class. When you realize that sites which uses RS contains many classes, so one more class is just a simple thing. Because to me it looks much more complicated to think up and realize class for mysql or for management of the web content than to do this simple class. I know it can look complicated because it has methods, but this is exactly what I see as advantage. Classes benefit is that they bring more readability to the code... Of sore, reading a simple file is very short code, but also you must read and compare much more data...

 

I am not sure If I mentioned the concept of the container. I have reserved 250 bytes for three numbers of IP, which is 750 per a "row". So when you have IP 124.1.2.3 then I find the row 124 which is on position 750*124 - 1. The row of 750 is divided to 250 because 250 for second number, 250 for third number and 250 for fourth number. Now when I search for IP I have two approches

and I must decide which one is better?

 

A) either read first byte of the row (1st byte of the 1st segment:i) and then compare it with the second number of IP. If this is equal, so I seek for the second segment first byte (i+500) and compare with third number. If it is equal, so I do the same for the fourth number (i=750). I can repeat it as many times as needed. Of sure, that if there is not equality, than is will not be returned false (existing item). This means, that it will skip most of the bytes. I think there should be about 3-10 IPS in every row, so I read about cca 5-30 bytes only. But the problem here can be the fseek, which mean often to change the position to read.

 

B) another solution would be to read all 3 segments to variables $a=fread($fh,250);$b=fread($fh,250);$c=fread($fh,250); and then when they are in RAM memory do quick comparison with for loop. This would also read about 5-30 bytes, but the difference is that it would read whole 750 bytes and fseek would be called only 1x. So what approach could be better? What do you think?

Edited by murfy
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.