2012-05-17 21 views
13

Tôi có một thư mục với 1,3 triệu tệp mà tôi cần chuyển vào cơ sở dữ liệu. Tôi chỉ cần lấy một tên tập tin duy nhất từ ​​thư mục KHÔNG quét toàn bộ thư mục. Nó không quan trọng mà tập tin tôi lấy như tôi sẽ xóa nó khi tôi đang thực hiện với nó và sau đó chuyển sang kế tiếp. Điều này có thể không? Tất cả các ví dụ tôi có thể tìm thấy dường như quét toàn bộ danh sách thư mục thành một mảng. Tôi chỉ cần lấy một lúc để xử lý ... không phải 1,3 triệu lần.PHP: Làm thế nào tôi có thể lấy một tệp từ một thư mục mà không cần quét toàn bộ thư mục?

+0

@JonathanSampson Tôi nghi ngờ anh ấy quan tâm đến tên tệp. Anh ta muốn lấy bất kỳ tập tin nào, đặt nó vào cơ sở dữ liệu, và chuyển sang tệp tiếp theo. –

Trả lời

19

này nên làm điều đó:

<?php 
$h = opendir('./'); //Open the current directory 
while (false !== ($entry = readdir($h))) { 
    if($entry != '.' && $entry != '..') { //Skips over . and .. 
     echo $entry; //Do whatever you need to do with the file 
     break; //Exit the loop so no more files are read 
    } 
} 
?> 

readdir

Trả về tên của mục tiếp theo trong danh bạ. Các mục được trả về theo thứ tự mà chúng được lưu trữ bởi hệ thống tập tin.

+0

Tôi muốn chèn '.'and' .. 'vào cơ sở dữ liệu hơn là kiểm tra 1.3 triệu lần. –

+0

@SamyDindane, Việc kiểm tra đó sẽ không mất nhiều thời gian, đặc biệt so với việc đọc tệp từ đĩa và lưu trữ nó trong cơ sở dữ liệu ... – Zombaya

+2

Tuy nhiên, có thể tránh được phí trên (mọi trợ giúp) chỉ bằng cách thực hiện hai cuộc gọi đến 'readdir' trước vòng lặp, như' .' và '..' luôn là các mục đầu tiên. – connec

2

readdir sẽ thực hiện thủ thuật. Kiểm tra các exampl trên trang đó, nhưng thay vì thực hiện cuộc gọi readdir trong vòng lặp, chỉ cần làm điều đó một lần. Bạn sẽ nhận được tệp đầu tiên trong thư mục.

Lưu ý: bạn có thể nhận được ".", ".." và các phản hồi tương tự khác tùy thuộc vào máy chủ, vì vậy bạn có thể muốn ít nhất lặp cho đến khi bạn nhận được tệp hợp lệ.

5

Chỉ cần có được các thư mục iterator và tìm kiếm các mục nhập đầu tiên mà là một tập tin:

foreach(new DirectoryIterator('.') as $file) 
{ 
    if ($file->isFile()) { 
     echo $file, "\n"; 
     break; 
    }   
} 

này cũng đảm bảo rằng mã của bạn được thực hiện trên một số hành vi tập tin hệ thống khác so với cái mà bạn mong đợi.

Xem DirectoryIteratorSplFileInfo.

+0

Tuy nhiên, điều này không tải toàn bộ nội dung thư mục vào một mảng? Đó là những gì Kyle đang cố gắng tránh.Điều đó có thể tạo sự khác biệt khi bạn có hàng ngàn tệp trong thư mục. – skibulk

+1

@skibulk: Không, nó lặp lại qua ** DirectoryIterator ** không phải là mảng mà là một đối tượng. Điều này ngăn chặn hiệu quả những gì bạn sợ: một mảng. – hakre

+0

Tuyệt. Tôi đã quen với các mảng 'foreach'ing. Vì vậy, khi 'foreach' truy cập vào chỉ mục tiếp theo của' DirectoryIterator', nó thực sự gọi một phương thức (IE getNextFile()) thay vào đó? Lạ thật. – skibulk

0

bạn có muốn trả lại thư mục đầu tiên HOẶC tệp đầu tiên không? cả hai? sử dụng này:

tạo chức năng "pickfirst" với 2 lập luận

function pickfirst($address,$file) { // $file=false >> pick first dir , $file=true >> pick first file 
$h = opendir($address); 

    while (false !== ($entry = readdir($h))) { 

      if($entry != '.' && $entry != '..' && (($file==false && !is_file($address.$entry)) || ($file==true && is_file($address.$entry))) ) 
      { return $entry; break; } 

} // end while 
} // end function 

nếu bạn muốn chọn thư mục đầu tiên trong địa chỉ của bạn thiết lập $file false và nếu bạn muốn chọn đầu tiên (địa chỉ và chế độ dir hoặc nộp?) trong tập hợp địa chỉ $file của bạn thành sự thật.

chúc may mắn :)

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