Jawaban:
Deskriptor file adalah "pegangan" integer tingkat rendah yang digunakan untuk mengidentifikasi file yang dibuka (atau soket, atau apa pun) di tingkat kernel, di Linux dan sistem mirip Unix lainnya.
Anda meneruskan deskriptor file "polos" ke panggilan Unix yang sebenarnya, seperti read()
, write()
dan sebagainya.
Sebuah FILE
pointer adalah konstruksi tingkat perpustakaan standar C, digunakan untuk merepresentasikan file. The FILE
membungkus file descriptor, dan menambahkan buffering dan fitur lain untuk membuat I / O lebih mudah.
Anda meneruskan FILE
pointer ke fungsi C standar seperti fread()
dan fwrite()
.
fd
argumen pertama untuk read()
. Mengapa Anda menyebutnya telanjang?
FILE *
, deskriptor file integer adalah "kurang dibungkus", yaitu "telanjang".
Salah satunya adalah buffered ( FILE *
) dan yang lainnya tidak. Dalam praktiknya, Anda ingin menggunakan FILE *
hampir selalu saat Anda membaca dari file 'asli' (yaitu di drive), kecuali Anda tahu apa yang Anda lakukan atau kecuali file Anda sebenarnya adalah soket atau lebih ..
Anda bisa mendapatkan deskriptor file dari FILE *
penggunaan fileno()
dan Anda bisa membuka buffer FILE *
dari deskriptor file menggunakanfdopen()
Deskriptor file hanyalah bilangan bulat yang Anda peroleh dari open()
panggilan POSIX . Menggunakan standar C fopen()
Anda mendapatkan FILE
struct kembali. The FILE
struct berisi deskripsi file ini antara lain seperti akhir-of-file dan indikator kesalahan, posisi aliran dll
Jadi menggunakan fopen()
memberi Anda sejumlah abstraksi dibandingkan dengan open()
. Secara umum Anda harus menggunakan fopen()
karena itu lebih portabel dan Anda dapat menggunakan semua fungsi C standar lainnya yang menggunakan FILE
struct, yaitu, fprintf()
dan keluarga.
Tidak ada masalah kinerja saat menggunakannya.
Deskriptor file vs Penunjuk file
Deskriptor file:
File Descriptor adalah nilai integer yang dikembalikan oleh open()
panggilan sistem.
int fd = open (filePath, mode);
Penunjuk file:
Penunjuk File adalah penunjuk ke struktur C yang dikembalikan oleh fopen()
fungsi pustaka, yang digunakan untuk mengidentifikasi file, membungkus deskriptor file, fungsi buffering, dan semua fungsi lain yang diperlukan untuk operasi I / O. Penunjuk file berjenis FILE , yang definisinya dapat ditemukan di "/usr/include/stdio.h" . Definisi ini mungkin berbeda dari satu kompilator ke kompiler lainnya.
FILE *fp = fopen (filePath, mode);
// A FILE Structure returned by fopen
typedef struct
{
unsigned char *_ptr;
int _cnt;
unsigned char *_base;
unsigned char *_bufendp;
short _flag;
short _file;
int __stdioid;
char *__newbase;
#ifdef _THREAD_SAFE
void *_lock;
#else
long _unused[1];
#endif
#ifdef __64BIT__
long _unused1[4];
#endif /* __64BIT__ */
} FILE;
Ingin menambahkan poin yang mungkin berguna.
TENTANG FILE *
Saya menggunakannya berkali-kali untuk log debug. contoh,
FILE *fp;
fp = fopen("debug.txt","a");
fprintf(fp,"I have reached till this point");
fclose(fp);
TENTANG FILE DESCRIPTOR
Ini umumnya digunakan untuk IPC.
Memberikan kontrol tingkat rendah ke file di sistem * nix. (Perangkat, file, soket, dll), sehingga lebih kuat daripada FILE *
.
fdopen()
untuk melakukan hal-hal seperti IPC dan perangkat dengan FILE*
?
FILE*
, tetapi Anda dapat membuat FILE*
dari deskriptor file ( fdopen()
) dan menutupnya nanti juga FILE
akan menutup deskriptor. Oleh karena itu, Anda dapat melakukan IPC, tetapi Anda harus berurusan dengan deskriptor file sedikit untuk memfasilitasi IPC langsung.
FILE *
lebih berguna ketika Anda bekerja dengan file teks dan user input / output, karena memungkinkan Anda untuk menggunakan fungsi API seperti sprintf()
, sscanf()
, fgets()
, feof()
dll
API deskriptor file adalah level rendah, sehingga memungkinkan untuk bekerja dengan soket, pipa, file yang dipetakan memori (dan file biasa, tentu saja).
Sekadar catatan untuk menyelesaikan diskusi (jika tertarik) ....
fopen
bisa jadi tidak aman, dan Anda mungkin harus menggunakan fopen_s
atau open
dengan kumpulan bit eksklusif. C1X menawarkan x
mode, sehingga Anda dapat fopen
dengan mode "rx"
, "wx"
, dll
Jika Anda menggunakan open
, Anda mungkin mempertimbangkan open(..., O_EXCL | O_RDONLY,... )
atau open(..., O_CREAT | O_EXCL | O_WRONLY,... )
.
Lihat, sebagai contoh, Jangan membuat asumsi tentang fopen () dan pembuatan file .
fopen_s
tampaknya tidak tersedia dengan POSIX
, saya berasumsi solusi yang paling portabel adalah untuk open(2)
dan kemudian fdopen(2)
. (menyisihkan jendela). Juga, apa yang lebih cepat fopen_s()
atau open(2)
diikuti fdopen(2)
?
Panggilan sistem sebagian besar menggunakan deskriptor file, misalnya read
dan write
. Fungsi perpustakaan akan menggunakan penunjuk file ( printf
, scanf
). Namun, fungsi perpustakaan hanya menggunakan panggilan sistem internal.
Saya menemukan sumber daya yang bagus di sini , memberikan gambaran umum tingkat tinggi tentang perbedaan antara keduanya:
Ketika Anda ingin melakukan input atau output ke sebuah file, Anda memiliki dua pilihan mekanisme dasar untuk merepresentasikan koneksi antara program Anda dan file: deskriptor dan aliran file. Deskriptor file direpresentasikan sebagai objek bertipe int, sedangkan aliran direpresentasikan sebagai objek FILE *.
Deskriptor file menyediakan antarmuka tingkat rendah yang primitif untuk operasi input dan output. Baik deskriptor dan aliran file dapat mewakili koneksi ke perangkat (seperti terminal), atau pipa atau soket untuk berkomunikasi dengan proses lain, serta file normal. Tetapi, jika Anda ingin melakukan operasi kontrol yang khusus untuk jenis perangkat tertentu, Anda harus menggunakan deskriptor file; tidak ada fasilitas untuk menggunakan aliran dengan cara ini. Anda juga harus menggunakan deskriptor file jika program Anda perlu melakukan input atau output dalam mode khusus, seperti input nonblocking (atau polling) (lihat Bendera Status File).
Stream menyediakan antarmuka tingkat yang lebih tinggi, yang dilapisi di atas fasilitas deskriptor file primitif. Antarmuka aliran memperlakukan semua jenis file hampir sama — satu-satunya pengecualian adalah tiga gaya buffering yang dapat Anda pilih (lihat Stream Buffering).
Keuntungan utama menggunakan antarmuka aliran adalah bahwa serangkaian fungsi untuk melakukan operasi input dan output aktual (sebagai lawan operasi kontrol) pada aliran jauh lebih kaya dan lebih kuat daripada fasilitas terkait untuk deskriptor file. Antarmuka deskriptor file hanya menyediakan fungsi sederhana untuk mentransfer blok karakter, tetapi antarmuka aliran juga menyediakan fungsi masukan dan keluaran yang diformat kuat (printf dan scanf) serta fungsi untuk masukan dan keluaran berorientasi karakter dan garis.
Karena aliran diterapkan dalam hal deskriptor file, Anda dapat mengekstrak deskriptor file dari aliran dan melakukan operasi tingkat rendah langsung pada deskriptor file. Pada awalnya Anda juga dapat membuka koneksi sebagai deskriptor file, lalu membuat streaming yang terkait dengan deskriptor file tersebut.
Secara umum, Anda harus tetap menggunakan stream daripada deskriptor file, kecuali ada beberapa operasi tertentu yang ingin Anda lakukan yang hanya dapat dilakukan pada deskriptor file. Jika Anda seorang pemrogram pemula dan tidak yakin fungsi apa yang akan digunakan, kami sarankan Anda berkonsentrasi pada fungsi masukan yang diformat (lihat Input yang Diformat) dan fungsi keluaran yang diformat (lihat Output yang Diformat).
Jika Anda khawatir tentang portabilitas program Anda ke sistem selain GNU, Anda juga harus menyadari bahwa deskriptor file tidak portabel seperti streaming. Anda dapat mengharapkan sistem apa pun yang menjalankan ISO C untuk mendukung streaming, tetapi sistem non-GNU mungkin tidak mendukung deskriptor file sama sekali, atau mungkin hanya mengimplementasikan subset dari fungsi GNU yang beroperasi pada deskriptor file. Akan tetapi, sebagian besar fungsi deskriptor file dalam GNU C Library termasuk dalam standar POSIX.1.