Anda akan perlu menggunakan fungsi perpustakaan untuk mengambil detail file. Karena C sepenuhnya tidak bergantung pada platform, Anda harus memberi tahu kami platform / sistem operasi apa yang Anda kembangkan!
Chris Roberts
Kenapa char* filekenapa tidak FILE* file? -1
-1 karena fungsi file harus menerima deskriptor file bukan jalur file
Pada sistem 32-bit Anda harus mengkompilasi ini dengan opsi -D_FILE_OFFSET_BITS=64, jika tidak off_thanya akan menyimpan nilai hingga 2 GB. Lihat bagian "Menggunakan LFS" dari Dukungan File Besar di Linux untuk detailnya.
Ini khusus untuk Linux / Unix - mungkin perlu ditunjukkan karena pertanyaannya tidak menentukan OS.
Drew Hall
1
Anda mungkin dapat mengubah tipe pengembalian ke ssize_t dan mengubah ukuran dari off_t tanpa masalah. Tampaknya lebih masuk akal untuk menggunakan ssize_t :-) (Jangan bingung dengan size_t yang tidak bertanda tangan dan tidak dapat digunakan untuk menunjukkan kesalahan.)
Ted Percival
1
Untuk kode yang lebih portabel, gunakan fseek+ ftellseperti yang diusulkan oleh Derek.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
9
Untuk kode yang lebih portabel, gunakan fseek+ ftellseperti yang diusulkan oleh Derek. Tidak The C Standard secara khusus menyatakan bahwa fseek()untuk SEEK_ENDpada file biner adalah perilaku undefined. 7.19.9.2 fseekFungsi ... Aliran biner tidak perlu secara berarti mendukung fseekpanggilan dengan nilai dari manaSEEK_END , dan seperti yang disebutkan di bawah ini, yang berasal dari catatan kaki 234 di hal. 267 dari C Standard terkait, dan yang secara khusus label fseekuntuk SEEK_ENDdalam aliran biner sebagai perilaku undefined. .
Andrew Henle
Dari gnu libc manual : ... Sistem [non-POSIX] membuat perbedaan antara file yang berisi teks dan file yang berisi data biner, dan fasilitas input dan output ISO C menyediakan perbedaan ini. ... Di GNU C Library, dan di semua sistem POSIX, tidak ada perbedaan antara aliran teks dan aliran biner. Saat Anda membuka aliran, Anda mendapatkan jenis aliran yang sama terlepas dari apakah Anda meminta biner. Aliran ini dapat menangani konten file apa pun, dan tidak memiliki batasan yang terkadang dimiliki aliran teks.
Bocah Kecil
75
Jangan gunakan int. File berukuran lebih dari 2 gigabyte umum sebagai kotoran hari ini
Jangan gunakan unsigned int. File berukuran lebih dari 4 gigabyte biasa terjadi sebagai kotoran yang sedikit kurang umum
IIRC yang didefinisikan oleh pustaka standar off_t sebagai integer 64 bit unsigned, yang harus digunakan setiap orang. Kami dapat mendefinisikan ulang itu menjadi 128 bit dalam beberapa tahun ketika kami mulai memiliki 16 file exabyte berkeliaran.
Jika Anda menggunakan windows, Anda harus menggunakan GetFileSizeEx - ini sebenarnya menggunakan integer 64 bit yang ditandatangani, jadi mereka akan mulai mengalami masalah dengan 8 file exabyte. Microsoft yang bodoh! :-)
Saya telah menggunakan kompiler di mana off_t adalah 32 bit. Memang, ini ada di sistem tertanam di mana file 4GB kurang umum. Bagaimanapun, POSIX juga mendefinisikan off64_t dan metode terkait untuk menambah kebingungan.
Aaron Campbell
Saya selalu menyukai jawaban yang mengasumsikan Windows dan tidak melakukan apa-apa selain mengkritik pertanyaan itu. Bisakah Anda menambahkan sesuatu yang sesuai dengan POSIX?
SS Anne
1
@ JL2210 jawaban yang diterima dari Ted Percival menunjukkan solusi yang sesuai dengan posix, jadi saya tidak melihat ada gunanya mengulangi yang sudah jelas. Saya (dan 70 lainnya) berpikir bahwa menambahkan catatan tentang windows dan tidak menggunakan bilangan bulat 32 bit yang ditandatangani untuk mewakili ukuran file adalah nilai tambah di atas itu. Cheers
Orion Edwards
31
Solusi Matt seharusnya berfungsi, kecuali bahwa itu C ++, bukan C, dan perintah awal seharusnya tidak diperlukan.
unsignedlongfsize(char* file){
FILE * f = fopen(file, "r");
fseek(f, 0, SEEK_END);
unsignedlong len = (unsignedlong)ftell(f);
fclose(f);
return len;
}
Memperbaiki brace untuk Anda juga. ;)
Pembaruan: Ini sebenarnya bukan solusi terbaik. Ini terbatas pada file 4GB di Windows dan kemungkinan lebih lambat daripada hanya menggunakan panggilan khusus platform seperti GetFileSizeExatau stat64.
Ya kamu harus. Namun, kecuali ada alasan yang sangat kuat untuk tidak menulis khusus platform, Anda mungkin sebaiknya hanya menggunakan panggilan khusus platform daripada pola buka / seek-end / beri tahu / tutup.
Derek Park
1
Maaf atas balasan yang terlambat, tetapi saya mengalami masalah besar di sini. Itu menyebabkan aplikasi macet saat mengakses file yang dibatasi (seperti dilindungi kata sandi atau file sistem). Apakah ada cara untuk meminta kata sandi kepada pengguna saat dibutuhkan?
Justin
@Justin, Anda mungkin harus membuka pertanyaan baru secara khusus tentang masalah yang Anda hadapi, dan memberikan detail tentang platform yang Anda gunakan, bagaimana Anda mengakses file, dan apa perilakunya.
Derek Park
1
Baik C99 dan C11 kembali long intdari ftell(). (unsigned long)casting tidak meningkatkan jangkauan karena telah dibatasi oleh fungsinya. ftell()return -1 on error dan itu dikaburkan dengan cast. Sarankan fsize()kembalikan tipe yang sama seperti ftell().
chux
Saya setuju. Pemerannya harus mencocokkan prototipe asli dalam pertanyaan itu. Saya tidak dapat mengingat mengapa saya mengubahnya menjadi unsigned long dan bukan unsigned int.
Mengutip dokumen standar C99 yang saya temukan online: "Menyetel indikator posisi file ke akhir file, seperti halnya fseek(file, 0, SEEK_END), memiliki perilaku tidak terdefinisi untuk aliran biner (karena kemungkinan karakter null tertinggal) atau untuk aliran apa pun dengan pengkodean yang bergantung pada status yang tidak pasti berakhir pada status shift awal. **
Ubah definisi menjadi int agar pesan kesalahan dapat dikirim, kemudian gunakan fseek()dan ftell()untuk menentukan ukuran file.
@mezhaka: Laporan CERT itu salah. fseekodan ftello(atau fseekdan ftelljika Anda terjebak tanpa yang pertama dan senang dengan batasan ukuran file yang dapat Anda gunakan) adalah cara yang tepat untuk menentukan panjang file. statsolusi berbasis tidak bekerja pada banyak "file" (seperti perangkat blok) dan tidak portabel ke sistem non-POSIX-ish.
R .. GitHub STOP HELPING ICE
1
Ini adalah satu-satunya cara untuk mendapatkan ukuran file pada banyak sistem non-posix compliant (seperti mbed saya yang sangat minimalis)
Earlz
9
POSIX
Standar POSIX memiliki metode sendiri untuk mendapatkan ukuran file.
Sertakansys/stat.h tajuk untuk menggunakan fungsi tersebut.
Catatan : Ini membatasi ukuran 4GB. Jika bukan Fat32filesystem, gunakan versi 64bit!
#include<stdio.h>#include<sys/stat.h>intmain(int argc, char** argv){
structstatinfo;
stat(argv[1], &info);
// 'st' is an acronym of 'stat'printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include<stdio.h>#include<sys/stat.h>intmain(int argc, char** argv){
structstat64info;
stat64(argv[1], &info);
// 'st' is an acronym of 'stat'printf("%s: size=%ld\n", argv[1], info.st_size);
}
ANSI C (standar)
The ANSI C tidak secara langsung menyediakan cara untuk menentukan panjang file.
Kita harus menggunakan pikiran kita. Untuk saat ini, kami akan menggunakan pendekatan seek!
Itu bukan standar C. Ini bagian dari standar POSIX, tapi bukan standar C.
Derek Park
4
Dan jika Anda membuat aplikasi Windows, gunakan GetFileSizeEx API karena file CRT I / O berantakan, terutama untuk menentukan panjang file, karena kekhasan dalam representasi file pada sistem yang berbeda;)
Pencarian cepat di Google menemukan metode menggunakan fseek dan ftell dan utas dengan pertanyaan ini dengan jawaban yang tidak dapat dilakukan hanya dalam C dengan cara lain.
Anda dapat menggunakan pustaka portabilitas seperti NSPR (pustaka yang mendukung Firefox) atau memeriksa implementasinya (agak berbulu).
Saya menggunakan rangkaian kode ini untuk menemukan panjang file.
//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");
//gets a long from the file descriptor for fstatlong f_d = fileno(i_file);
structstatbuffer;
fstat(f_d, &buffer);
//stores file sizelong file_length = buffer.st_size;
fclose(i_file);
Apa yang dilakukan ini adalah yang pertama, cari ke akhir file; lalu, laporkan lokasi penunjuk file. Terakhir (ini opsional) itu mundur kembali ke awal file. Perhatikan bahwa fpharus aliran biner.
file_size berisi jumlah byte yang dimiliki file. Perhatikan bahwa karena (menurut climits.h) tipe panjang unsigned dibatasi hingga 4294967295 byte (4 gigabyte) Anda perlu mencari tipe variabel yang berbeda jika Anda cenderung menangani file yang lebih besar dari itu.
Itu adalah perilaku yang tidak ditentukan untuk aliran biner, dan untuk aliran teks ftelltidak mengembalikan nilai yang mewakili jumlah byte yang dapat dibaca dari file.
Andrew Henle
0
Saya memiliki fungsi yang hanya berfungsi dengan baik stdio.h. Saya sangat menyukainya dan bekerja dengan sangat baik dan cukup ringkas:
Pendekatannya benar-benar salah, Itu konstan yang ftellakan kembali 0setiap saat!
Jawaban ini benar-benar salah, karena untuk satu, Anda harus menggunakan fseek()pertama untuk mencari akhir file, dan juga, ftell()mengharapkan a FILE *, bukan string! Anda akan dilayani dengan baik untuk menyempurnakan jawaban Anda.
char* file
kenapa tidakFILE* file
? -1Jawaban:
Berdasarkan kode NilObject:
#include <sys/stat.h> #include <sys/types.h> off_t fsize(const char *filename) { struct stat st; if (stat(filename, &st) == 0) return st.st_size; return -1; }
Perubahan:
const char
.struct stat
definisi, yang nama variabelnya hilang.-1
kesalahan, bukan0
, yang akan menjadi ambigu untuk file kosong.off_t
adalah tipe yang ditandatangani jadi ini mungkin.jika kamu mau
fsize()
mencetak pesan tentang kesalahan, Anda dapat menggunakan ini:#include <sys/stat.h> #include <sys/types.h> #include <string.h> #include <stdio.h> #include <errno.h> off_t fsize(const char *filename) { struct stat st; if (stat(filename, &st) == 0) return st.st_size; fprintf(stderr, "Cannot determine size of %s: %s\n", filename, strerror(errno)); return -1; }
Pada sistem 32-bit Anda harus mengkompilasi ini dengan opsi
-D_FILE_OFFSET_BITS=64
, jika tidakoff_t
hanya akan menyimpan nilai hingga 2 GB. Lihat bagian "Menggunakan LFS" dari Dukungan File Besar di Linux untuk detailnya.sumber
fseek
+ftell
seperti yang diusulkan oleh Derek.fseek
+ftell
seperti yang diusulkan oleh Derek. Tidak The C Standard secara khusus menyatakan bahwafseek()
untukSEEK_END
pada file biner adalah perilaku undefined. 7.19.9.2fseek
Fungsi ... Aliran biner tidak perlu secara berarti mendukungfseek
panggilan dengan nilai dari manaSEEK_END
, dan seperti yang disebutkan di bawah ini, yang berasal dari catatan kaki 234 di hal. 267 dari C Standard terkait, dan yang secara khusus labelfseek
untukSEEK_END
dalam aliran biner sebagai perilaku undefined. .Jangan gunakan
int
. File berukuran lebih dari 2 gigabyte umum sebagai kotoran hari iniJangan gunakan
unsigned int
. File berukuran lebih dari 4 gigabyte biasa terjadi sebagai kotoran yang sedikit kurang umumIIRC yang didefinisikan oleh pustaka standar
off_t
sebagai integer 64 bit unsigned, yang harus digunakan setiap orang. Kami dapat mendefinisikan ulang itu menjadi 128 bit dalam beberapa tahun ketika kami mulai memiliki 16 file exabyte berkeliaran.Jika Anda menggunakan windows, Anda harus menggunakan GetFileSizeEx - ini sebenarnya menggunakan integer 64 bit yang ditandatangani, jadi mereka akan mulai mengalami masalah dengan 8 file exabyte. Microsoft yang bodoh! :-)
sumber
Solusi Matt seharusnya berfungsi, kecuali bahwa itu C ++, bukan C, dan perintah awal seharusnya tidak diperlukan.
unsigned long fsize(char* file) { FILE * f = fopen(file, "r"); fseek(f, 0, SEEK_END); unsigned long len = (unsigned long)ftell(f); fclose(f); return len; }
Memperbaiki brace untuk Anda juga. ;)
Pembaruan: Ini sebenarnya bukan solusi terbaik. Ini terbatas pada file 4GB di Windows dan kemungkinan lebih lambat daripada hanya menggunakan panggilan khusus platform seperti
GetFileSizeEx
ataustat64
.sumber
long int
dariftell()
.(unsigned long)
casting tidak meningkatkan jangkauan karena telah dibatasi oleh fungsinya.ftell()
return -1 on error dan itu dikaburkan dengan cast. Sarankanfsize()
kembalikan tipe yang sama sepertiftell()
.** Jangan lakukan ini ( mengapa? ):
Ubah definisi menjadi int agar pesan kesalahan dapat dikirim, kemudian gunakan
fseek()
danftell()
untuk menentukan ukuran file.int fsize(char* file) { int size; FILE* fh; fh = fopen(file, "rb"); //binary mode if(fh != NULL){ if( fseek(fh, 0, SEEK_END) ){ fclose(fh); return -1; } size = ftell(fh); fclose(fh); return size; } return -1; //error }
sumber
fseeko
danftello
(ataufseek
danftell
jika Anda terjebak tanpa yang pertama dan senang dengan batasan ukuran file yang dapat Anda gunakan) adalah cara yang tepat untuk menentukan panjang file.stat
solusi berbasis tidak bekerja pada banyak "file" (seperti perangkat blok) dan tidak portabel ke sistem non-POSIX-ish.POSIX
Standar POSIX memiliki metode sendiri untuk mendapatkan ukuran file.
Sertakan
sys/stat.h
tajuk untuk menggunakan fungsi tersebut.Ringkasan
stat(3)
.st_size
propertinya.Contoh
Catatan : Ini membatasi ukuran
4GB
. Jika bukanFat32
filesystem, gunakan versi 64bit!#include <stdio.h> #include <sys/stat.h> int main(int argc, char** argv) { struct stat info; stat(argv[1], &info); // 'st' is an acronym of 'stat' printf("%s: size=%ld\n", argv[1], info.st_size); }
#include <stdio.h> #include <sys/stat.h> int main(int argc, char** argv) { struct stat64 info; stat64(argv[1], &info); // 'st' is an acronym of 'stat' printf("%s: size=%ld\n", argv[1], info.st_size); }
ANSI C (standar)
The ANSI C tidak secara langsung menyediakan cara untuk menentukan panjang file.
Kita harus menggunakan pikiran kita. Untuk saat ini, kami akan menggunakan pendekatan seek!
Ringkasan
fseek(3)
.ftell(3)
.Contoh
#include <stdio.h> int main(int argc, char** argv) { FILE* fp = fopen(argv[1]); int f_size; fseek(fp, 0, SEEK_END); f_size = ftell(fp); rewind(fp); // to back to start again printf("%s: size=%ld", (unsigned long)f_size); }
sumber
struct _stat64
dan__stat64()
untuk _Windows.Jika Anda baik-baik saja menggunakan pustaka std c:
#include <sys/stat.h> off_t fsize(char *file) { struct stat filestat; if (stat(file, &filestat) == 0) { return filestat.st_size; } return 0; }
sumber
Dan jika Anda membuat aplikasi Windows, gunakan GetFileSizeEx API karena file CRT I / O berantakan, terutama untuk menentukan panjang file, karena kekhasan dalam representasi file pada sistem yang berbeda;)
sumber
Pencarian cepat di Google menemukan metode menggunakan fseek dan ftell dan utas dengan pertanyaan ini dengan jawaban yang tidak dapat dilakukan hanya dalam C dengan cara lain.
Anda dapat menggunakan pustaka portabilitas seperti NSPR (pustaka yang mendukung Firefox) atau memeriksa implementasinya (agak berbulu).
sumber
Saya menggunakan rangkaian kode ini untuk menemukan panjang file.
//opens a file with a file descriptor FILE * i_file; i_file = fopen(source, "r"); //gets a long from the file descriptor for fstat long f_d = fileno(i_file); struct stat buffer; fstat(f_d, &buffer); //stores file size long file_length = buffer.st_size; fclose(i_file);
sumber
Coba ini --
fseek(fp, 0, SEEK_END); unsigned long int file_size = ftell(fp); rewind(fp);
Apa yang dilakukan ini adalah yang pertama, cari ke akhir file; lalu, laporkan lokasi penunjuk file. Terakhir (ini opsional) itu mundur kembali ke awal file. Perhatikan bahwa
fp
harus aliran biner.file_size berisi jumlah byte yang dimiliki file. Perhatikan bahwa karena (menurut climits.h) tipe panjang unsigned dibatasi hingga 4294967295 byte (4 gigabyte) Anda perlu mencari tipe variabel yang berbeda jika Anda cenderung menangani file yang lebih besar dari itu.
sumber
ftell
tidak mengembalikan nilai yang mewakili jumlah byte yang dapat dibaca dari file.Saya memiliki fungsi yang hanya berfungsi dengan baik
stdio.h
. Saya sangat menyukainya dan bekerja dengan sangat baik dan cukup ringkas:size_t fsize(FILE *File) { size_t FSZ; fseek(File, 0, 2); FSZ = ftell(File); rewind(File); return FSZ; }
sumber
Berikut adalah fungsi sederhana dan bersih yang mengembalikan ukuran file.
long get_file_size(char *path) { FILE *fp; long size = -1; /* Open file for reading */ fp = fopen(path, "r"); fseek(fp, 0, SEEK_END); size = ftell(fp); fp.close(); return }
sumber
Anda dapat membuka file, pergi ke 0 relatif offset dari bagian bawah file dengan
#define SEEKBOTTOM 2 fseek(handle, 0, SEEKBOTTOM)
nilai yang dikembalikan dari fseek adalah ukuran file.
Saya tidak membuat kode dalam C untuk waktu yang lama, tetapi saya pikir itu harus berhasil.
sumber
Melihat pertanyaan itu,
ftell
dengan mudah bisa mendapatkan jumlah byte.long size = ftell(FILENAME); printf("total size is %ld bytes",size);
sumber
ftell
mengharapkan deskriptor file, bukan nama file, sebagai argumen.ftell
tidak mengharapkan deskriptor file,FILE*
melainkan. Lihat halaman manual dulu!ftell
akan kembali0
setiap saat!fseek()
pertama untuk mencari akhir file, dan juga,ftell()
mengharapkan aFILE *
, bukan string! Anda akan dilayani dengan baik untuk menyempurnakan jawaban Anda.