文件句柄?文件描述符?傻傻分不清楚

2021-03-02 朱小廝的博客
概述

在實際工作中會經常遇到一些bug,有些就需要用到文件句柄,文件描述符等概念,比如報錯: too many open files, 如果你對相關知識一無所知,那麼debug起來將會異常痛苦。在linux作業系統中,文件句柄(包括Socket句柄)、打開文件、文件指針、文件描述符的概念比較繞,而且windows的文件句柄又與此有何關聯和區別?這一系列的問題是我們不得不面對的。

筆者通過翻閱相關資料,並採用了一些demo來驗證相關觀點。如果文中有理解偏差,歡迎指正。

這裡先籠統的將一下筆者對上面的問題的一些理解:

句柄,熟悉Windows編程的人知道,句柄是Windows用來標識被應用程式所建立或使用的對象的唯一整數,windows使用各種各樣的句柄標識諸如應用程式實例、窗口、控制、位圖等。Windows的句柄有點像C語言中的文件句柄。更通俗的理解,句柄是一種指向指針的指針。

在linux系統中文件句柄(file handles)和文件描述符(file descriptor)是一個一一對應的關係(如果錯誤,歡迎指正),按照C語言的理解文件句柄是FILE*(fopen()返回),而文件描述符是fd(int型,open()函數返回),FILE這個結構體中有一個欄位是_fileno,其就是指fd(文章末尾通過程序驗證),且FILE*和fd可以通過C語言函數進行互相轉換,故此筆者認為linux的文件句柄和文件描述符應該是一個一一對應的關係。文件指針即指FILE*,即指文件句柄。打開文件(open files)包括文件句柄但不僅限於文件句柄,由於linux所有的事物都以文件的形式存在,要使用諸如共享內存、信號量、消息隊列、內存映射等都會打開文件,但這些是不會佔用文件句柄。

ulimit

查看進程允許打開的最大文件句柄數:ulimit -n。設置進程能打開的最大文件句柄數:ulimit -n xxx。

ulimit在系統允許的情況下,提供對特定shell可利用的資源的控制(Provides control over the resources avaliable to the shell and to processes started by it, on systems that allow such control)。-H和-S選項設定指定資源的硬限制和軟限制。硬限制設定之後不能再添加,而軟限制則可以增加到硬限制規定的值。如果-H和-S選項都沒有指定,則軟限制和硬限制同時設定。限制值可以是指定資源的數值或者hard, soft, unlimited這些特殊值,其中hard代表當前硬限制, soft代表當前軟體限制, unlimited代表不限制. 如果不指定限制值, 則列印指定資源的軟限制值, 除非指定了-H選項.如果指定了不只一種資源, 則限制名和單位都會在限制值前顯示出來.

[root@hidden ~]
1024
[root@hidden ~]
4096

需要注意的是ulimit提供的是對特定shell可利用的資源的控制,而shell是與具體用戶相關的。因此ulimit提供的是對單個用戶的限制。包括以下項:

[root@hidden ~]
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62799
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 65536
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

其中就有個「open files」的限制,默認是1024,也就是這個用戶最大可以打開1024個文件。如果使用ulimit -n修改最大文件打開數,那麼只對當前shell用戶有用,同時也只對當前shell和這個shell fork出來的子shell生效,重啟之後會重新恢復為默認值。

limits.conf

limits.conf這個文件是在/etc/security/目錄下,因此這個文件是出於安全考慮的。limits.conf文件是用於提供對系統中的用戶所使用的資源進行控制和限制,對所有用戶的資源設定限制是非常重要的,這可以防止用戶發起針對處理器和內存數量等的拒絕服務攻擊。這些限制必須在用戶登錄時限制。

[root@hidden ~]
(省略若干....)

apps soft nofile 65535
apps hard nofile 65535
apps soft nproc 10240
apps hard nproc 10240

其中含義如下:

第一列表示域(domain),可以使用用戶名(root等),組名(以@開頭),通配置*和%,%可以用於%group參數。

第二列表示類型(type),值可以是soft或者hard

第三列表示項目(item),值可以是core, data, fsize, memlock, nofile, rss, stack, cpu, nproc, as, maxlogins, maxsyslogins, priority, locks, msgqueue, nie, rtprio。其中nofile(Number of Open File)就是文件打開數。

第四列表示值.

關於第三列的詳細解釋如下:




















limits.conf與ulimit的區別在於前者是針對所有用戶的,而且在任何shell都是生效的,即與shell無關,而後者只是針對特定用戶的當前shell的設定。在修改最大文件打開數時,最好使用limits.conf文件來修改,通過這個文件,可以定義用戶,資源類型,軟硬限制等。也可修改/etc/profile文件加上ulimit的設置語句來是的全局生效。
當達到上限時,會報錯:too many open files或者遇上Socket/File: Cannot open so many files等。

file-max & file-nr

[root@hidden ~]
798282
[root@hidden fd]
fs.file-max = 798282

該文件指定了可以分配的文件句柄的最大數目(系統全局的可用句柄數目. The value in file-max denotes the maximum number of file handles that the Linux kernel will allocate)。如果用戶得到的錯誤消息諸如「由於打開文件數已經達到了最大值」之類,那麼說明他們不能打開更多文件,則可能需要增加該值。可將這個值設置成任意多個文件,並且能通過將一個新數字值寫入該文件來更改該值。這個參數的默認值和內存大小有關係,可以使用公式:file-max ≈ 內存大小/ 10k.

[root@hidden ~]
1440        0   798282

關於file-nr參數的解釋如下:
Historically, the three values in file-nr denoted the number of allocated file handles, the number of allocated but unused file handles, and the maximum number of file handles. Linux 2.6 always reports 0 as the number of free file handles – this is not an error, it just means that the number of allocated file handles exactly matches the number of used file handles.

這三個值分別指:系統已經分配出去的句柄數、已經分配但是還沒有使用的句柄數以及系統最大的句柄數(和file-max一樣)。

[root@hidden fd]
2538

lsof是列出系統所佔用的資源(list open files),但是這些資源不一定會佔用句柄。比如共享內存、信號量、消息隊列、內存映射等,雖然佔用了這些資源,但不佔用句柄。
如果出了某些故障,使用lsof | wc -l的結果,這個時候可以通過file-nr粗略的估算一下。

查看硬碟信息:df -m
查看內存信息:free -m
查看CPU信息:cat /proc/cpuinfo
查看內核所能打開的線程數:cat /proc/sys/kernel/threads-max

為什麼有限制?

為什麼Linux內核對文件句柄數、線程和進程的最大打開數進行了限制?以及如果我們把它調的太大,會產生什麼樣的後果?

原因1 - 資源問題:the operating system needs memory to manage each open file, and memory is a limited resource - especially on embedded systems.
原因2 - 安全問題:if there were no limits, a userland software would be able to create files endlessly until the server goes down.

What’s more? If the file descriptors are tcp sockets, etc, then you risk using up a large amount for the socket buffers and other kernel objects, this memory is not going to be swappable.

最主要的是資源問題,為防止某一單一進程打開過多文件描述符而耗盡系統資源,對進程打開文件數做了限制。

lsof

lsof(list open files)是一個列出當前系統打開文件的工具。在linux環境下,任何事物都以文件的形式存在,通過文件不僅僅可以訪問常規數據,還可以訪問網絡連接和硬體。所以如TCP和UDP等,系統在後臺都為該應用程式分配了一個文件描述符,無論這個文件的本質如何,該文件描述符為應用程式與基礎作業系統之間的交互提供了通用接口。因為應用程式打開文件的描述符列表提供了大量關於這個應用程式本身的信息,因此通過lsof工具能夠查看這個列表對系統檢測以及拍錯將是很有幫助的。

在終端下輸入lsof即可顯示系統打開的文件,因為lsof需要訪問核心內存和各種文件,所以必須以root身份運行它才能夠充分地發揮其功能。

[root@hidden linuxC]
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
java    14895 root  cwd    DIR              252,1     4096 1310824 /root/util/kafka_2.10-0.8.2.1
java    14895 root  rtd    DIR              252,1     4096       2 /
java    14895 root  txt    REG              252,1     7734 1583642 /root/util/jdk1.8.0_112/bin/java
java    14895 root  mem    REG              252,1 10485760 1325066 /tmp/kafka-logs/default_channel_kafka_zzh_demo-4/00000000000003626728.index
...(省略若干)
java    14895 root   85u   REG              252,1        0 1311594 /tmp/kafka-logs/default_channel_kafka_zzh_demo-4/00000000000003626728.log
java    14895 root   87u   REG              252,1        0 1325038 /tmp/kafka-logs/default_channel_kafka_zzh_demo-3/00000000000003915669.log
java    14895 root   88u  IPv6           40855648      0t0     TCP zhuzhonghua2-fqawb:XmlIpcRegSvc->xx.xx.139.85:64708 (ESTABLISHED)
java    14895 root   89u   REG              252,1        0 1325037 /tmp/kafka-logs/default_channel_kafka_zzh_demo-2/00000000000005892533.log
java    14895 root   93u   REG              252,1        0 1325040 /tmp/kafka-logs/default_channel_kafka_zzh_demo-1/00000000000005494790.log
java    14895 root   94u   REG              252,1        0 1325043 /tmp/kafka-logs/default_channel_kafka_zzh_demo-0/00000000000003858999.log
[root@hidden linuxC]
89
[root@hidden linuxC]
0  10  12  14  16  18  2   21  23  25  27  29  30  32  34  36  38  4   41  43  45  47  49  50  52  54  56  58  6   61  63  65  67  69  70  72  75  77  79  80  82  85  88  9   94
1  11  13  15  17  19  20  22  24  26  28  3   31  33  35  37  39  40  42  44  46  48  5   51  53  55  57  59  60  62  64  66  68  7   71  74  76  78  8   81  83  87  89  93

lsof輸出各列信息的意義如下:

COMMAND:進程的名稱
PID: 進程標識符
USER:進程所有者
FD:文件描述符,應用程式通過文件描述符識別該文件。如cwd, rtd, txt, mem, DEL, 0u, 3w, 4r等
TYPE:文件類型,如DIR, REG, CHR, Ipv6, unix, FIFO等
DEVICE:指定磁碟的名稱
SIZE/OFF:文件的大小
NODE:索引節點
NAME:打開文件的確切名稱

FD列中的文件描述符cwd表示應用程式的當前工作目錄,這是該應用程式啟動的目錄,除非它本身對這個目錄進行更改;txt類型的文件是程序代碼,如應用程式二進位文件本身或共享庫,如上列表中顯示的、sbin/init程序;數值表示應用程式的文件描述符,這是打開該文件時返回的一個整數,如「lsof -p 14895」命令解析出來的最後一行的文件描述符為94,u表示該文件被打開處於讀寫模式,而不是只讀r或只寫w模式,同時還有大寫的W表示該應用程式具有對整個文件的寫鎖。該文件描述符用於確保每次只能打開一個應用程式實例。初始打開每個應用程式時,都有三個文件描述符:0、1、2,分別表示標準輸入、標準輸出、錯誤流。所以大多數應用程式所打開的文件的FD都是從3開始的。

TYPE列比較直觀。文件和目錄分別為REG和DIR。而CHR和BLK分別表示字符和塊設備。或者unix, FIFO, Ipv6分表表示UNIX域套接字,FIFO隊列和IP套接字。

查看當前進程打開了多少文件:lsof -n|awk 『{print $2}』|sort|uniq -c|sort -nr|more | grep [PID]

[root@hidden fd]
    173 14895

第一列是句柄數,第二列是進程號PID.

[root@hidden proc]
174

這裡多了一個是由於:

COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
java    14895 root  cwd    DIR              252,1     4096 1310824 /root/util/kafka_2.10-0.8.2.1
java    14895 root  rtd    DIR              252,1     4096       2 /
java    14895 root  txt    REG              252,1     7734 1583642 /root/util/jdk1.8.0_112/bin/java
java    14895 root  mem    REG              252,1 10485760 1325066 /tmp/kafka-logs/default_channel_kafka_zzh_demo-4/00000000000003626728.index
java    14895 root  mem    REG              252,1 10485760 1325044 /tmp/kafka-logs/default_channel_kafka_zzh_demo-0/00000000000003858999.index
java    14895 root  mem    REG              252,1 10485760 1325042 /tmp/kafka-logs/default_channel_kafka_zzh_demo-2/00000000000005892533.index
java    14895 root  mem    REG              252,1 10485760 1325041 /tmp/kafka-logs/default_channel_kafka_zzh_demo-1/00000000000005494790.index
....(省略若干)
java    14895 root   85u   REG              252,1        0 1311594 /tmp/kafka-logs/default_channel_kafka_zzh_demo-4/00000000000003626728.log
java    14895 root   87u   REG              252,1        0 1325038 /tmp/kafka-logs/default_channel_kafka_zzh_demo-3/00000000000003915669.log
java    14895 root   88u  IPv6           40855648      0t0     TCP zhuzhonghua2-fqawb:XmlIpcRegSvc->xx.xx.139.85:64708 (ESTABLISHED)
java    14895 root   89u   REG              252,1        0 1325037 /tmp/kafka-logs/default_channel_kafka_zzh_demo-2/00000000000005892533.log
java    14895 root   93u   REG              252,1        0 1325040 /tmp/kafka-logs/default_channel_kafka_zzh_demo-1/00000000000005494790.log
java    14895 root   94u   REG              252,1        0 1325043 /tmp/kafka-logs/default_channel_kafka_zzh_demo-0/00000000000003858999.log

多了「COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME」這一行。
而文件描述符的個數為90:

[root@zhuzhonghua2-fqawb linuxC]
90
[root@zhuzhonghua2-fqawb linuxC]
0  10  12  14  16  18  2   21  23  25  27  29  30  32  34  36  38  4   41  43  45  47  49  50  52  54  56  58  6   61  63  65  67  69  70  72  75  77  79  80  82  84  87  89  93
1  11  13  15  17  19  20  22  24  26  28  3   31  33  35  37  39  40  42  44  46  48  5   51  53  55  57  59  60  62  64  66  68  7   71  74  76  78  8   81  83  85  88  9   94

文件描述符(file descriptor)

對於linux而言,所有對設備和文件的操作都使用文件描述符來進行的。文件描述符是一個非負的整數,它是一個索引值,指向內核中每個進程打開文件的記錄表。當打開一個現存文件或創建一個新文件時,內核就向進程返回一個文件描述符;當需要讀寫文件時,也需要把文件描述符作為參數傳遞給相應的函數。
通常,一個進程啟動時,都會打開3個文件:標準輸入、標準輸出和標準出錯處理。這3個文件分別對應文件描述符為0、1和2(宏STD_FILENO、STDOUT_FILENO和STDERR_FILENO)。

每一個文件描述符會與一個打開文件相對應,同時,不同的文件描述符也會指向同一個文件。相同的文件可以被不同的進程打開也可以在同一個進程中被多次打開。系統為每一個進程維護了一個文件描述符表,該表的值都是從0開始的,所以在不同的進程中你會看到相同的文件描述符,這種情況下相同文件描述符有可能指向同一個文件,也有可能指向不同的文件。具體情況要具體分析,要理解具體其概況如何,需要查看由內核維護的3個數據結構。

進程級的文件描述符表

系統級的打開文件描述符表

文件系統的i-node表

由於進程級文件描述符表的存在,不同的進程中會出現相同的文件描述符,它們可能指向同一個文件,也可能指向不同的文件。兩個不同的文件描述符,若指向同一個打開文件句柄,將共享同一文件偏移量。因此,如果通過其中一個文件描述符來修改文件偏移量,那麼從另一個文件描述符中也會觀察到變化,無論這兩個文件描述符是否屬於不同進程,還是同一個進程,情況都是如此。

文件句柄 vs 文件描述符

文件句柄也稱為文件指針(FILE *):C語言中使用文件指針做為I/O的句柄。文件指針指向進程用戶區中的一個被稱為FILE結構的數據結構。FILE結構包括一個緩衝區和一個文件描述符。而文件描述符是文件描述符表的一個索引,因此從某種意義上說文件指針就是句柄的句柄(在Windows系統上,文件描述符被稱作文件句柄)。

C語言中FILE結構體的定義:


struct _IO_FILE;

__BEGIN_NAMESPACE_STD

typedef struct _IO_FILE FILE;
__END_NAMESPACE_STD
#if defined __USE_LARGEFILE64 || defined __USE_SVID || defined __USE_POSIX \
    || defined __USE_BSD || defined __USE_ISOC99 || defined __USE_XOPEN \
    || defined __USE_POSIX2
__USING_NAMESPACE_STD(FILE)
#endif

# define __FILE_defined 1
#endif 
#undef  __need_FILE


#if !defined ____FILE_defined && defined __need___FILE


typedef struct _IO_FILE __FILE;

struct _IO_FILE {
int _flags; 
#define _IO_file_flags _flags



char* _IO_read_ptr; 
char* _IO_read_end; 
char* _IO_read_base; 
char* _IO_write_base; 
char* _IO_write_ptr; 
char* _IO_write_end; 
char* _IO_buf_base; 
char* _IO_buf_end; 

char *_IO_save_base; 
char *_IO_backup_base; 
char *_IO_save_end; 

struct _IO_marker *_markers;

struct _IO_FILE *_chain;

int _fileno;
#if 0
int _blksize;
#else
int _flags2;
#endif
_IO_off_t _old_offset; 

#define __HAVE_COLUMN 

unsigned short _cur_column;

signed char _vtable_offset;
char _shortbuf[1];



_IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};

這個_IO_FILE結構體中的「int _fileno」就是fd,即文件描述符。這個可以通過程序驗證:

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>

int main(){
        char buf[50] = {"file descriptor demo"};
        FILE *myfile;

        myfile = fopen("test","w+");
        if(!myfile){
                printf("error: openfile failed!\n");
        }
        printf("The openfile's descriptor is %d\n", myfile->_fileno);
        if(write(myfile->_fileno,buf,50)<0){
                perror("error: write file failed!\n");
                exit(1);
        }else{
                printf("writefile successed!\n");
        }

        exit(0);
}

編譯:g++ fileno.cpp -o fileno.out
執行+輸出:

[root@hidden linuxC]
The openfile's descriptor is 3
writefile successed!

查看test文件:

[root@hidden linuxC]
file descriptor demo

相關焦點

  • 多進程中之文件描述符繼承的消除
    什麼是文件描述符的繼承當父進程創建子進程時,無論 fork 函數或者是 vfork 函數,子進程通常都會繼承父進程的文件描述符。所謂的繼承,就是子進程可以使用相同的文件描述符,和父進程操作同一個文件對象。如圖所示父子進程共享文件描述符這種可能會造成權限安全隱患。怎麼辦呢?
  • Linux 進程、線程、文件描述符的底層原理
    struct fs_struct      *fs;    // 一個數組,包含該進程打開的文件指針    struct files_struct   *files;};task_struct就是 Linux 內核對於一個進程的描述,也可以稱為「進程描述符」。
  • 數據恢復:如何恢復Linux中意外刪除的文件
    4. dbwr 會打開所有數據文件的句柄。在 proc 目錄中可以查到,目錄名是進程 PID,fd 表示文件描述符。,為了在 Solaris 系統中確認哪個句柄對應哪個文件,則需要使用 lsof 程序。
  • 一個案例輕鬆認識Python文件處理-提取文件中的數字
    1、文件打開 使用 open() 函數打開文件。它需要兩個參數,第一個參數是文件路徑或文件名,第二個是文件的打開模式。模式通常是下面這樣的: "r",以只讀模式打開,你只能讀取文件但不能編輯/刪除文件的任何內容 "w",以寫入模式打開,如果文件存在將會刪除裡面的所有內容,然後打開這個文件進行寫入 "a",以追加模式打開,寫入到文件中的任何數據將自動添加到末尾 默認的模式為只讀模式
  • ARM系列之分散加載描述符(scatte)文件的應用
    在上一篇中,提到了分散加載描述符的應用場景。一般對於簡單的代碼分布,不需要使用這樣的文件,直接藉助於編譯器中的simple選項,配置入口地址,RW和RO地址就可以運行了。如下圖所示:這樣最終生成的燒入ROM或Flash中的鏡像文件就不包括那部分分割了的零初始化段,即使該零初始化段再大,也不影響最終生成的鏡像文件的大小。但不採用分散加載機制,零初始化段在編譯連接後是直接生成到鏡像文件中的。
  • Delphi基礎教程圖文版之文件操作
    數據流(Data Stream):數據在數據源和程序(內存)之間傳遞的過程輸入流(Input Stream):數據從數據源到程序(內存)的過程輸出流(Output Stream):從程序(內存)到數據源的過程其實Delphi針對文件操作這塊的內容提供了 3 套 API 的支持,在網絡上查詢的過程中大部分 Delphi 文件操作這塊的實現都是利用的
  • Node.js 高級進階之 fs 文件模塊學習
    今日文章由 「程式設計師成長指北@koala」 授權分享,正文從下面開始~前言文件操作是開發過程中並不可少的一部分,作為一名 Node.js
  • 描述文件是什麼 iOS12描述文件知識掃盲
    對於果粉用戶來說「描述文件」肯定不會陌生,在升級iOS測試版或公測版的時候都需要用到這個。不過知道,並多不代表真的懂,那麼,究竟描述文件是什麼,它有什麼用,怎麼用呢?
  • 談一談 Python 文件讀寫的細節
    1.文件讀寫的流程1)類比windows中手動操作txt文檔,說明python中如何操作txt文件?① windows中手動操作txt文件的步驟② python操作txt文件的步驟獲取被打開的文件的內存對象,該內存對象又叫做文件句柄通過這個內存對象(文件句柄),來對文件進行操作(讀取,寫入等操作)2)什麼是文件的內存對象(文件句柄)?
  • Python文件目錄操作就是這麼6
    /OS/一、文件操作(os直屬常用方法)# 關閉文件描述符 hwos.close(hw) # 關閉所有文件描述符,從 hw1(包含) 到 hw2(不包含), 錯誤會忽略os.closerange(hw1,hw2
  • CSV文件存儲
    該文件是一個字符序列,可以由任意數目的記錄組成,記錄間以某種換行符分隔。每條記錄由欄位組成,欄位間的分隔符是其他字符或字符串,最常見的是逗號或制表符。不過所有記錄都有完全相同的欄位序列,相當於一個結構化表的純文本形式。它比 Excel 文件更加簡潔, XLS 文本是電子表格,它包含了文本、數值、公式和格式等內容,而 CSV 中不包含這些內容,就是特定字符分割的純文本,結構簡單清晰。
  • 【iOS】描述文件刪除不了?教你一鍵移除所有惡意描述文件
    有個大兄弟微信求助,說他在網頁上安裝了一個這樣的第三方的「視頻學習軟體」,但是現在想刪除App卻發現無法移除描述文件,屏幕長按刪除也沒法刪除軟體,很是著急這種加入Web Clip 就能讓安裝的用戶,無刪除除描述文件。今天就給各位介紹一個方法,只要你有發現到iOS 設備上有看見無法刪除的App 或描述文件,你就可以通過這方法解決。
  • 通過fd文件描述符獲取文件絕對地址
    若參數bufsiz小於符號連接的內容長度,過長的內容會被截斷,如果 readlink 第一個參數指向一個文件而不是符號連結時,readlink 設 置errno 為 EINVAL 並返回 -1。readlink()函數組合了open()、read()和close()的所有操作。path是一個存在的軟連接。
  • 描述文件刪不掉?教你一招移除惡意描述文件
    原每日發文時間:20:00新每日發文時間:00:00有個大兄弟昨夜求助說自己手機裡有一個描述文件就是刪不掉這種加入Web Clip 就能讓安裝的用戶,無刪除除描述文件。控制面板--程序---啟用或關閉Windows功能---勾選「.NET Framework 3.5環境」安裝「移除描述文件工具(iPhone配置實用工具)」(文末裂開星球獲取)
  • 蘋果IOS9描述怎麼刪除?ios9描述文件刪除教程
    ios9描述文件刪除教程 果粉們在安裝IOS9系統後,設備中往往會出現ios9描述文件,很多果粉們都不清楚ios9描述文件是什麼,以及ios9描述文件可以刪除嗎?怎麼刪除?果粉們在安裝IOS9系統後,設備中往往會出現ios9描述文件,ios9描述文件估計使用幾年的果粉都不知道這是個什麼文件,同時也不知道ios9描述文件刪除後有什麼後果。
  • 如何在 Linux 伺服器上設置 ulimit 和文件描述符數限制 | Linux 中國
    簡介:在生產環境中遇到打開文件數這類的挑戰如今已是司空見慣的事情了。因為許多應用程式是基於 Java 和 Apache 的,安裝和配置它們可能會導致打開過多的文件(文件描述符)。如果打開的文件描述符超過了默認設置的限制,就可能會面臨訪問控制問題,受阻於打開文件的挑戰。許多生產環境因此而陷入停滯狀態。
  • iOS13描述文件可以刪除嗎?iPhone刪除描述文件圖文教程
    下面本文簡單科普下,描述文件是什麼、是否可以刪除以及如何刪除,希望對新手朋友有所幫助。描述文件是什麼?描述文件是蘋果作業系統,包括iOS、iPadOS、watchOS、macOS、tvOS等系統的一種配置文件,裡面包含了設備的一些授權信息,如網絡配置、訪問限制、安全策略等等。
  • ios描述文件怎麼刪除?刪除iOS12公測版描述文件的方法
    通過ios描述文件來升級相應的系統版本,是許多蘋果手機用戶都會選擇的系統升級方式,不過,在升級最新系統之後,需要把手機中原有系統的ios描述文件刪除掉,那麼,ios描述文件怎麼刪除?我們就以最近發布的iOS12公測版描述文件為例子進行講解,下面,給大家帶來刪除iOS12公測版描述文件的方法!
  • iOS12描述文件可以刪除嗎 升級後怎麼刪除描述文件方法
    升級到iOS12測試版之後,如何刪掉下載的描述文件呢?下面小編本文統一解答一下。  Q:iOS描述文件可以刪除嗎?  A:iOS 的「描述文件」是一個設置文件,實質是一個XML文件,不是證書。安裝iOS描述文件,成功升級系統之後,描述文件是可以刪除的。