2013-10-08 17 views
12

Hiện nay tôi đang làm nó như thế này:Làm thế nào để viết lại cùng một tập tin

$f = fopen('test', 'w'); 
fwrite($f, 'Hi'); 
fclose($f); 

Nhưng tôi có một vòng lặp mà không một số công cụ đắt tiền (với các tập tin), và tôi muốn tránh mở và đóng nộp xử lý mỗi khi tôi muốn ghi đè lên "test"

Nó phải là một cái gì đó như thế này:

$f = fopen('test', 'w'); 

$i = 0; 
while($ < 50000){ 

    $i++; 
    foverwrite($f, 'i = ' . $i); 

    sleep(5); // just a example 

} 

fclose($f); 

đây có phải là có thể?

Tập lệnh này chạy ở chế độ nền trong chế độ CLI và tôi đang đọc tệp thử nghiệm từ web với ajax cứ 2 giây một lần. Về cơ bản tôi đang cố gắng hiển thị thanh tiến trình lol

+0

Bạn đang thực sự cố gắng đạt được điều gì? AKA, đầu ra của tệp của bạn trước và sau là gì? – zonzon

+1

Tại sao bạn không chỉ chuẩn bị một chuỗi bên trong vòng lặp đó, và sau đó ghi nó vào một tập tin? – Yang

+0

Nhưng đó là những gì tôi đang làm, $ i là chuỗi :) zonzon: nó sẽ chỉ là một dòng: i = number (số thay đổi trong vòng lặp) – thelolcat

Trả lời

2

Để đi cùng với ví dụ của bạn, bạn có thể thực hiện chức năng foverwrite() bạn sử dụng frewind() như thế này:

function foverwrite($handle,$content) 
    { 
    frewind($handle); 
    return fwrite($handle,$content); 
    } 

Chức năng này sẽ trở lại giá trị trả về fwrite() 's, vì vậy nó có thể dễ dàng thay thế fwrite() nếu cần. Ngoài ra, trong trường hợp mở tệp ở chế độ chắp thêm (a hoặc a +), nó sẽ chỉ nối thêm các contens, vì frewind() sẽ không tạo ra sự khác biệt nào.

Tuy nhiên, liên quan đến mục đích của kịch bản của bạn, mà rõ ràng là interprocess communication, bạn nên có một cái nhìn tại các kỹ thuật hiệu quả hơn, như shared memory.

9

Bạn có thể cập nhật nội dung của tệp bằng cách tua lại con trỏ tệp, xem fseek(). Hãy cẩn thận, khi bạn đặt chiều dài tập tin thành N bằng cách viết N byte cho nó, lần sau, nếu bạn tua lại và viết X < N byte, tệp sẽ giữ nguyên N byte, chứa X byte dữ liệu mới và byte NX của nội dung cũ .

Dù sao, đừng lo lắng về việc mở và đóng tệp nhiều lần, chúng sẽ được lưu vào bộ nhớ cache. Hoặc bạn có thể mở nó trên một phân vùng ramdisk.

1

Bạn có thể làm điều đó trong những cách sau đây

$data = [];//initiate the $data variable as empty array 
$i = 0; 
while($i < 50000){ 

    $data[] = 'i = ' . $i; 
    $i++; 
} 
file_put_contents('file.txt', implode("\n", $data));// implode the array 
+0

Bạn có nghĩa là '$ i <50000' là điều kiện không? (Hiện tại bạn chỉ có '$' cho biến). – Flexo

8

Bạn có thể giữ các tập tin và chỉ cần viết lại về nội dung, thời gian sau đó cắt bỏ các tập tin nếu kích thước thay đổi. Điều này sẽ nhanh hơn ghi đè hoặc xóa và viết lại.

$f = fopen('test', 'w'); 
$i = 0; 
while($i < 50000){ 
    $i++; 

    rewind($f); 
    $data = 'i = ' . $i; 
    fwrite($f, $data); 
    ftruncate($f, strlen($data)); // <---------- Here's the ticket 

    sleep(5); 
} 

fclose($f); 
1

Nếu bạn chỉ nhằm giữ một tập tin được cập nhật để nó có thể được truy cập bởi các yêu cầu AJAX, sau đó bạn thực sự cần phải cập nhật nó 50000 lần? Một cách đơn giản để cắt giảm chi phí của bạn là cập nhật tệp ít thường xuyên hơn. Như thế này, ví dụ:

for ($i=0; $i<50000; $i++) { 

    // update progress file every 1000 iterations: 
    if (!($i % 1000)) file_put_contents('./file.txt', "i = $i"); 

    // --- do stuff --- 

} 
file_put_contents($f, "i = 50000"); 
Các vấn đề liên quan