2012-03-26 42 views
7

Tôi đã tự hỏi liệu có ai biết điều này có thể được thực hiện trong PHP hay không. Tôi đang chạy một kịch bản có liên quan đến việc mở một tệp, lấy 1000 dòng đầu tiên, thực hiện một số nội dung với các dòng đó, sau đó tệp php sẽ mở một phiên bản khác để lấy hàng nghìn dòng tiếp theo và tiếp tục cho đến khi nó kết thúc tệp . Tôi đang sử dụng splfileobject để tôi có thể tìm kiếm một dòng nhất định, điều này cho phép tôi chia nhỏ thành 1000 dòng khối khá tốt. Vấn đề lớn nhất mà tôi gặp phải là với hiệu suất. Tôi đang xử lý các tệp có tối đa 10.000.000 dòng và trong khi nó có 10.000 dòng đầu tiên hoặc quá nhanh, có một sự sụt giảm theo cấp số nhân rất lớn sau thời điểm đó mà tôi nghĩ là chỉ cần tìm đến điểm đó.Xóa các dòng X đầu tiên khỏi một tệp PHP

Điều tôi muốn làm là đọc 1000 dòng đầu tiên, sau đó chỉ cần xóa chúng khỏi tệp sao cho tập lệnh của tôi luôn đọc nghìn dòng đầu tiên. Có cách nào để làm điều này mà không đọc phần còn lại của tập tin vào bộ nhớ. Các giải pháp khác tôi đã thấy liên quan đến việc đọc từng dòng vào một mảng sau đó loại bỏ các mục X đầu tiên, nhưng với mười triệu dòng sẽ ăn quá nhiều bộ nhớ và thời gian.

Nếu bất kỳ ai có giải pháp hoặc đề xuất khác có thể tăng tốc hiệu suất, nó sẽ được đánh giá cao.

+0

Bạn * nghĩ * đã mất thời gian tìm kiếm? – salathe

+0

Tôi nhận xét ra dòng mà lặp dòng truy cập để nó luôn chạy 1000 đầu tiên và nó chạy theo cấp số nhân nhanh hơn.Cộng với điều này được chậm hơn theo cấp số nhân khi nó đi cùng, điều duy nhất thats thay đổi là dòng mà nó đang tìm kiếm. –

+0

Tìm kiếm không nên dùng * theo cấp số nhân * thêm thời gian. Trên quy mô loại nào là sự suy giảm? – salathe

Trả lời

1

Thật không may là không có giải pháp thực sự cho điều này vì các tệp luôn được tải đầy đủ vào bộ nhớ chính trước khi chúng được đọc.

Tuy nhiên, tôi đã đăng câu trả lời này vì đây là giải pháp khả thi nhưng tôi nghi ngờ nó hầu như không cải thiện hiệu suất. Đúng nếu tôi đã sai lầm.

Bạn có thể sử dụng XML để chia tệp thành các đơn vị 1000 dòng. Và sử dụng lớp DomDocument của PHP để lấy và nối thêm dữ liệu. Bạn có thể chắp thêm con khi bạn muốn thêm dữ liệu và truy xuất con đầu tiên để nhận được hàng nghìn dòng đầu tiên và xóa nút đó nếu bạn muốn. Chỉ cần như thế này:

<document> 
    <part> 
     . . . 
     Thousand lines here 
     . . . 
    </part> 
    <part> 
     . . . 
     Thousand lines here 
     . . . 
    </part> 
    <part> 
     . . . 
     Thousand lines here 
     . . . 
    </part> 
    . 
    . 
    . 
</document> 

một cách khác:

Nếu bạn thực sự chắc chắn về phá vỡ các phần vào chính xác 1000 dòng tại sao bạn không lưu nó trong một cơ sở dữ liệu với mỗi 1000 trong một dãy ghế khác ? Bằng cách này, bạn chắc chắn sẽ giảm bớt chi phí đọc/ghi tập tin và cải thiện hiệu suất.

1

Dường như với tôi rằng mục tiêu là để phân tích một lượng lớn dữ liệu và chèn nó vào một cơ sở dữ liệu? Nếu vậy, tôi không hiểu tại sao điều quan trọng là phải làm việc với chính xác 1000 dòng?

Tôi nghĩ tôi sẽ tiếp cận nó bằng cách đọc một đoạn dữ liệu lớn, nói 1 MB, vào bộ nhớ cùng một lúc, và sau đó quét ngược từ cuối đoạn trong bộ nhớ cho dòng cuối cùng kết thúc. Khi tôi có điều đó, tôi có thể lưu vị trí tệp và dữ liệu bổ sung mà tôi có (những gì còn lại từ dòng cuối cùng kết thúc cho đến cuối đoạn). Ngoài ra, chỉ cần thiết lập lại con trỏ tập tin bằng cách sử dụng fseek() đến nơi trong tập tin mà tôi tìm thấy dòng cuối cùng kết thúc, dễ dàng thực hiện với strlen ($ chunk). Bằng cách đó, tất cả những gì tôi phải làm là phát nổ đoạn bằng cách chạy phát nổ ("\ r \ n", $ chunk) và tôi có tất cả các dòng tôi cần, trong một khối lớn phù hợp để xử lý tiếp.

Không thể xóa các dòng từ đầu tệp. Điều đó sẽ đẩy nhanh một lượng dữ liệu khổng lồ tới đĩa.

Các vấn đề liên quan