[TOC]
# 文件系統概述
### 文件的類型
在程序運行時,程序本身和數據一般都存在內存中,當程序運行結束后,存放在內存中的數據被釋放。
如果需要長期保存程序運行所需的原始數據,或程序運行產生的結果,就必須以文件形式存儲到外部存儲介質上。
文件一般指存儲在外部介質上具有名字(文件名)的一組相關數據集合。用文件可長期保存數據,并實現數據共享。
PHP是以UNIX的文件系統為模型的。因此在Windows系統中我們只能獲得”file”、”dir”或者“unknown”三種文件類型。而在UNIX系統中,我們可以獲得block、char、dir、fifo、file、link和unknown七種類型。
可以使用函數filetype()獲取文件的具體類型。
```
語法:string filetype ( string filename )
```
| 文件類型 | 描述 |
| --- | --- |
| block | 塊設備文件,如某個磁盤分區,軟驅,光驅CD-ROM等 |
| char | 字符設備是指在I/O傳輸過程中以字符為單位進行傳輸的設備,如鍵盤、打印機等 |
| dir | 目錄類型,目錄也是文件的一種 |
| fifo | 命名管道,常用于將信息從一個進程傳遞到另一個進程 |
| file | 普通文件類型,如文本文件或可執行文件等 |
| link | 符號鏈接,是指向文件指針的指針。類似Windows中的快捷方式 |
| unknow | 位置類型 |
* `is_dir( )` -- 判斷給定文件名是否是一個目錄
語法結構:bool is_dir(名稱)
返回類型:文件名存在并且是一個目錄則返回 true,否則返回 false。
* `is_executable( )` -- 判斷給定文件名是否可執行
語法結構:bool is_executable(名稱)
返回類型:如果文件存在且可執行則返回 true ,否則返回 false 。
* `is_file( )` -- 判斷給定文件名是否為一個正常的文件
語法結構:bool is_file(名稱)
返回類型:如果文件存在且為正常的文件則返回 true 。
* `is_link( )` -- 判斷給定文件名是否為一個符號連接
語法結構:bool is_link(名稱)
返回類型:如果文件存在并且是一個符號連接則返回 true。
* `is_readable( )` -- 判斷給定文件名是否可讀
語法結構:bool is_readable(文件名稱)
返回類型:如果文件存在并且可讀則返回 true 。
* `is_writable( )` -- 判斷給定的文件名是否可寫
語法結構:bool is_writable(文件名稱)
返回類型:如果文件存在并且可寫則返回 true 。
### 文件的屬性
|函數名|作用|參數|返回值|
|---|---|---|---|
|file_exists( ) | 檢查文件或目錄是否存在| 文件名 |存在:true,不存在:false|
|filesize() | 取得文件大小 |文件名 |返回大小字節數,出錯:false|
|is_readable() | 判斷文件是否可讀 | 文件名| 文件可讀返回true|
|is_writable() | 判斷文件是否可寫 | 文件名| 文件可寫返回true|
|is_executable()| 判斷文件是否可執行 | 文件名| 文件可執行返回true|
|filectime()| 獲取文件的創建時間 | 文件名| 返回UNIX時間戳格式|
|filemtime()| 獲取文件的修改時間 | 文件名| 返回UNIX時間戳格式|
|fileatime()| 獲取文件的訪問時間 | 文件名 |返回UNIX時間戳格式|
|stat() | 獲取文件大部分屬性 | 文件名 |返回給定屬性信息的數組|
# 目錄的基本操作
### 解析目錄路徑
使用PHP腳本可以方便對目錄進行操作,如創建目錄、遍歷目錄、復值目錄與刪除目錄等操作。
常用的文件目錄路徑格式:
```
$unixPath="/var/www/html/index.php";
//在UNIX系統中的絕對路徑,必須使用"/"分隔
$winPath="C:\\Appserv\\www\\index.php";
//在Windows系統的絕對路徑,默認使用"\"分隔
$winPath2="C:/Appserv/www/index.php";
//在Windows系統中也可使用“/”分隔。
```
注意使用絕對路徑與相對路徑。
* `basename`?--?返回路徑中的文件名部分
```
語法:string basename ( string path [, string suffix] )
```
給出一個包含有指向一個文件的全路徑的字符串,本函數返回基本的文件名。如果文件名是以 suffix 結束的,那這一部分也會被去掉。
* `dirname`?--?返回路徑中的目錄部分
```
語法:string dirname ( string path )
```
給出一個包含有指向一個文件的全路徑的字符串,本函數返回去掉文件名后的目錄名。
```
<?php
$path = "/home/httpd/html/index.php";
$file = basename($path); // $file值:"index.php"
$file = basename($path, ".php "); // $file值:"index "
$file = dirname($path); // $file值:"/home/httpd/html"
?>
```
* `pathinfo`?--?返回文件路徑的信息
```
語法:array pathinfo ( string path [, int options] )
```
pathinfo() 返回一個聯合數組包含有 path 的信息。包括以下的數組單元:dirname,basename 和 extension。
* `realpath`?--?返回規范化的絕對路徑名
```
語法:string realpath ( string path )
```
realpath() 擴展所有的符號連接并且處理輸入的 path 中的 '/./', '/../' 以及多余的 '/' 并返回規范化后的絕對路徑名。返回的路徑中沒有符號連接,'/./' 或 '/../' 成分。
```
<?php
$path_parts = pathinfo("/www/htdocs/index.html");
echo $path_parts["dirname"]."\n"; // /www/htdocs
echo $path_parts["basename"]."\n"; // index.html
echo $path_parts["extension"]."\n"; // html
?>
```
### 遍歷目錄
* `opendir`?--?打開目錄句柄
```
語法:resource opendir ( string path [, resource context] )
```
打開一個目錄句柄,可用于之后的 closedir(),readdir() 和 rewinddir() 調用中。
* `readdir`?--?從目錄句柄中讀取條目
```
語法:string readdir ( resource dir_handle )
```
返回當前目錄指針位置的文件名,沒有返回false,并將指針向下移動一位。文件名以在文件系統中的排序返回。
* `closedir`?--?關閉目錄句柄
```
語法:void closedir ( resource dir_handle )
```
關閉由 dir_handle 指定的目錄流。流必須之前被 opendir() 所打開。
* `rewinddir`?--?倒回目錄句柄
```
語法:void rewinddir ( resource dir_handle )
```
將 dir_handle 指定的目錄流重置到目錄的開頭。
```
<?php //遍歷指定目錄實例
$num=0; //用來統計子目錄和文件的個數
$dirname='phpMyAdmin'; //定義一個目錄名
$dir_handle=opendir($dirname); //用opendir打開目錄
//將遍歷的目錄和文件名使用表格格式輸出
while($file=readdir($dir_handle)) { //使用readdir循環讀取目錄里的內容
$dirFile=$dirname."/".$file; //追加目錄名
echo "文件名: ".$file." | "; //顯示文件名
echo "大小: ".filesize($dirFile)." | "; //顯示文件大小
echo "類型: ".filetype($dirFile)." | "; //顯示文件類型
echo "創建時間: ".date("Y/n/t",filectime($dirFile))."<br/>";
$num++;
}
closedir($dir_handle); //關閉文件操作句柄
echo '在<b>'.$dirname.'</b>目錄下共有文件<b>'.$num.'</b>個';
?>
```
### 統計目錄大小
* `disk_free_space`?--?返回目錄中的可用空間
```
語法:float disk_free_space ( string directory )
```
給出一個包含有一個目錄的字符串,本函數將根據相應的文件系統或磁盤分區返回可用的字節數。
* `disk_total_space`?--?返回一個目錄的磁盤總大小
```
語法:float disk_total_space ( string directory )
```
給出一個包含有一個目錄的字符串,本函數將根據相應的文件系統或磁盤分區返回所有的字節數。
```
<?php
//定義一個統計指定目錄大小的函數
function dirSize($dir){
$size=0;
//1. 判斷參數是否有效
if(!file_exists($dir) || !is_dir($dir)){
die("無效的參數!");
}
//2. 打開目錄
$dd = opendir($dir);
//3. 跳過連個特殊目錄:"."和".."
readdir($dd);readdir($dd);
//4. 開始遍歷目錄中文件
while($f = readdir($dd)){
//加上目錄名
$file = rtrim($dir,"/")."/".$f;
//判斷是否是文件
if(is_file($file)){
$size+=filesize($file);
}
//判斷是否是目錄
if(is_dir($file)){
//采用遞歸調用,統計子目錄大小
$size+=dirSize($file);
}
}
//5. 關閉目錄
closedir($dd);
//6. 返回結果
return $size;
}
echo dirSize('test');
?>
```
### 建立與刪除目錄
* `mkdir`?--?新建目錄
```
語法:bool mkdir (string pathname [,int mode])
```
嘗試新建一個由 pathname 指定的目錄。
* `rmdir`?--?刪除目錄
```
語法:bool rmdir ( string dirname )
```
嘗試刪除 dirname 所指定的目錄。 該目錄必須是空的,而且要有相應的權限。如果成功則返回 TRUE,失敗則返回 FALSE。
* `unlink`?--?刪除文件
```
語法:bool unlink ( string filename )
```
刪除 filename。和 Unix C 的 unlink() 函數相似。如果成功則返回 TRUE,失敗則返回 FALSE。
```
<?php
//自定義刪除目錄函數
function delDir($dir){
//1. 判斷是否是有效文件或目錄
if(!file_exists($dir)){
die("文件或目錄{$dir}不存在!");
}
//2. 若是文件就直接刪除
if(is_file($dir)){
unlink($dir);return true;
}
//3. 打開目錄
$dd = opendir($dir);
//4. 跳過兩個特殊目錄:"." ".."
readdir($dd);readdir($dd);
//5. 遍歷目錄,并刪除里面的文件
while($f = readdir($dd)){
//加上全路徑
$file = rtrim($dir,"/")."/".$f;
//判斷是否是目錄還是文件
if(is_dir($file)){
//采用遞歸調用刪除子目錄
delDir($file);
}else{
//刪除文件
unlink($file);
}
}
//6. 關閉目錄
closedir($dd);
//7. 刪除目錄
rmdir($dir);
return true;
}
?>
```
### 復制目錄
* `copy`?--?拷貝文件
```
語法:bool copy ( string source, string dest )
```
將文件從 source 拷貝到 dest。如果成功則返回 TRUE,失敗則返回 FALSE。
PHP中沒有提供復制與移動目錄的相關函數。如需要,只要自定義函數了。
如何定義一個目錄復制函數呢?
# 文件的基本操作
### 文件的打開與關閉
* `fopen`?--?打開文件或者 URL
```
語法:resource fopen ( string filename, string mode [, bool use_include_path [, resource zcontext]] )
```
filename參數需要提供要被打開文件的URL。這個URL可以是腳本所在的服務器中的絕對路徑,也可以是相對路徑,還可以是網絡資源用的文件。
mode 參數指定了所要求到該流的訪問類型,(強烈建議附加b模式)。
如果也需要在 include_path中搜尋文件的話,可以將可選的第三個參數 use_include_path 設為 '1' 或 TRUE。
如果打開失敗,本函數返回 FALSE。
* `fclose`?--?關閉一個已打開的文件指針
```
語法:bool fclose ( resource $handle )
```
將 handle 指向的文件關閉。 成功時返回 TRUE, 或者在失敗時返回 FALSE.
```
<?php
//使用絕對路徑打開file.txt文件,選擇只讀模式,并返回資源$handle
$handle = fopen("/home/rasmus/file.txt", "r");
//訪問文檔根目錄下的文件,也以只讀模式打開
$handle = fopen("{$_SERVER['DOCUMENT_ROOT']}/data/info.txt", "r");
//在 Windows 平臺上,轉義文件路徑中的每個反斜線,或者用斜線,以二進制和只寫模式組合
$handle = fopen("c:\\data\\file.gif", "wb");
//使用相對路徑打開file.txt文件,選擇只讀模式,并返回資源$handle
$handle = fopen("../data/info.txt", "r");
//打開遠程文件, 使用HTTP協議只能以只讀的模式打開
$handle = fopen("http://www.example.com/", "r");
//使用FTP協議打開遠程文件,如果FTP服務器可寫,則可以以寫的模式打開
$handle = fopen("ftp://user:password@example.com/somefile.txt", "w");
?>
```

### 寫入文件
* `fwrite`?--?寫入文件(可安全用于二進制文件)
```
語法:int fwrite ( resource handle, string string [, int length] )
```
fwrite() 把 string 的內容寫入 文件指針 handle 處。 如果指定了 length,當寫入了 length 個字節或者寫完了 string 以后,寫入就會停止,視乎先碰到哪種情況。
返回寫入的字符數,出現錯誤時則返回 FALSE 。
```
<?php
//聲明一個變量用來保存文件名
$fileName = "data.txt";
//使用fopen()函數以只寫的模式打開文件,如果不存在則創建它,
//打開失敗則通過程序
$handle = fopen($fileName, 'w') or die('打開<b>'.$fileName.'</b>文件失敗!!');
//循環10次寫入10行數據到文件中
for($row=0; $row<10; $row++) {
//寫入文件
fwrite($handle, $row.": www.baidu.com\n");
}
//關閉由fopen()打開的文件指針資源
fclose($handle);
?>
```
### 讀取文件內容
| 函數名 | 作用 |
| --- | --- |
| fread() | 讀取文件(可安全用于二進制文件) |
| file_get_contents() | 將文件讀入字符串 |
| fgets() | 從打開的文件中讀取一行 |
| fgetc() | 從打開的文件中讀取一個字符 |
| file() | 把文件讀入一個數組中(無需使用fopen打開) |
| readfile() | 讀取一個文件,并輸出到輸出緩沖(無需使用fopen打開) |
```
<?php
//從文件中讀取指定字節數的內容存入到一個變量中
$filename = "data.txt"; //將本地文件名保存在變量中
$handle = fopen($filename, "r") or die("文件打開失敗"); //以只讀的方式打開文件
$contents = fread($handle, 100); //讀取前100個字節;全部:filesize($filename)
fclose($handle); //關閉文件資源
// echo $contents; //將從文件中讀取的內容輸出
//從文件中讀取全部內容存入到一個變量中,每次讀取一部分,循環讀取
$handle = fopen ($filename, "rb") or die("文件打開失敗");
//以只讀的方式,模式加了’b’
$contents = "";
while (!feof($handle)) { //使用feof()判斷文件結尾
$contents .= fread($handle, 1024); //每次讀取1024個字節
}
fclose($handle); //關閉文件資源
echo $contents; //將從文件中讀取的全部內容輸出
?>
```
```
<?php
// echo file_get_contents("data.txt"); //讀取文本文件中的內容并輸出
$handle = fopen("data.txt", "r") or die("文件打開失敗"); //以只讀模式打開文件
while (!feof($handle)) { //循環讀取第一行
$buffer = fgets($handle, 4096); //一次讀取一行內容
echo $buffer."<br>"; //輸出每一行
}
fclose($handle); //關閉打開的文件資源
$fp = fopen('data.txt', 'r') or die("文件打開失敗"); //以只讀模式打開文件
while (false !== ($char = fgetc($fp))) { //在文件中每次循環讀取一個字節符
echo $char."<br>"; //輸出單個字符
}
print_r( file("test.txt") ); //將文件test.txt中的內容讀入到一個數組中,并輸出
readfile("data.txt"); //直接將文件data.txt中的數據讀出并輸出到瀏覽器
?>
```
### 移動文件指針
* `ftell`?--?返回文件指針讀/寫的位置
```
語法:int ftell ( resource handle )
```
返回由 handle 指定的文件指針的位置,也就是文件流中的偏移量。 如果出錯,返回 FALSE。文件指針必須是有效的,且必須指向一個通過 fopen()或 popen()成功打開的文件。
* `fseek`?--?在文件指針中定位
```
語法:int fseek ( resource handle,int offset [,int whence] )
```
在與 handle 關聯的文件中設定文件指針位置。新位置,從文件頭開始以字節數度量,是以 whence 指定的位置加上 offset。whence 的值定義為:
SEEK_SET - 設定位置等于 offset 字節。
SEEK_CUR - 設定位置為當前位置加上 offset。
SEEK_END - 設定位置為文件尾加上 offset。(要移動到文件尾之前的位置,需要給 offset 傳遞一個負值。)
如果 沒有指定 whence,默認為 SEEK_SET。
成功則返回 0;否則返回 -1。注意移動到 EOF 之后的位置不算錯誤
* `rewind`?--?倒回文件指針的位置
```
語法:bool rewind ( resource handle )
```
將 handle 的文件位置指針設為文件流的開頭。 如果成功則返回 TRUE,失敗則返回 FALSE。 文件指針必須合法,并且指向由 fopen() 成功打開的文件。
### 文件的一些基本操作函數
* `copy`?--?拷貝文件
```
語法:bool copy ( string source, string dest )
```
將文件從 source 拷貝到 dest。如果成功則返回 TRUE,失敗則返回 FALSE。
* `unlink`?--?刪除文件
```
語法:bool unlink ( string filename )
```
刪除 filename。和 Unix C 的 unlink() 函數相似。如果成功則返回 TRUE,失敗則返
回 FALSE。
* `ftruncate`?--?將文件截斷到給定的長度
```
語法:bool ftruncate ( resource handle, int size )
```
接受文件指針 handle 作為參數,并將文件大小截取為 size。如果成功則返回 TRUE,失敗則返回 FALSE。
* `rename`?--?重命名一個文件或目錄
```
語法:bool rename ( string oldname, string newname [, resource context] )
```
嘗試把 oldname 重命名為 newname。 如果成功則返回 TRUE,失敗則返回 FALSE。
> Have a try
1. 參考目錄統計大小函數,自定義一個刪除目錄的函數,注意目錄中的目錄。
2. 使用文件處理函數,自定義一個目錄復制函數。
3. 定義一個函數使用遞歸方式統計多維數組中的單元個數(遞歸函數練習)
- 前言
- Ⅰ.PHP基礎知識
- 1.PHP基本語法(一)
- 2.PHP基本語法(二)
- 3.流程控制結構
- 4.PHP函數
- 5.數組
- 6.字符串
- 7.PHP正則表達式
- 8.PHP的日期和時間
- 9.GD庫圖像處理
- 10.文件處理系統
- 11.文件上傳和下載
- 12.數據庫之MySQL(概述)
- Ⅱ.ThinkPHP5入門實踐
- 一、先看到頁面
- 1.1只展示頁面
- 1.2給視圖傳遞數據
- 1.3使用公共模板
- 1.4使用模板布局
- 二、簡單的數據庫操作
- (1)查
- (2)增
- (3)改
- (4)刪
- (5)鏈式操作
- 三、初級-階段性綜合應用
- (1)注冊
- (2)登錄
- 四、各種基本操作
- 1.操作Session
- 2.操作Cookie
- 3.文件上傳
- 五、富文本編輯器
- 集成wangEditor
- 集成UEditor
- 六、驗證碼
- 圖片驗證碼
- Ⅲ.常用類庫的使用
- 一、PHPExcel表格導入
- 二、PHPExcel表格導出
- 三、阿里大于短信驗證碼
- 四、時間戳操作Time
- 五、郵件發送
- 六、PHP操作Python
- Ⅳ.實例講解
- 一、病房管理系統
- 寫在前面
- 1.引導頁
- 2.公共模板
- 3.登錄
- 4.功能引導頁集合
- 5.修改密碼
- 6.員工信息注冊
- 7.員工信息更新
- 8.員工信息刪除
- 9.病人信息注冊
- 10.病人信息更新
- 11.出院手續辦理
- 12.病人信息刪除
- 13.科室信息查詢
- 14.醫護信息查詢
- 15.病房信息查詢
- 16.病歷信息查詢
- 加群驗證
- 必看推薦閱讀【不斷更新】