Bagaimana cara mengetahui ukuran file, dalam byte?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
Bagaimana cara mengetahui ukuran file, dalam byte?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
Jawaban:
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 tidak off_t
hanya akan menyimpan nilai hingga 2 GB. Lihat bagian "Menggunakan LFS" dari Dukungan File Besar di Linux untuk detailnya.
fseek
+ ftell
seperti yang diusulkan oleh Derek.
fseek
+ ftell
seperti yang diusulkan oleh Derek. Tidak The C Standard secara khusus menyatakan bahwa fseek()
untuk SEEK_END
pada file biner adalah perilaku undefined. 7.19.9.2 fseek
Fungsi ... Aliran biner tidak perlu secara berarti mendukung fseek
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 label fseek
untuk SEEK_END
dalam aliran biner sebagai perilaku undefined. .
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! :-)
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
atau stat64
.
long int
dari 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()
.
** Jangan lakukan ini ( mengapa? ):
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.
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
}
fseeko
dan ftello
(atau fseek
dan ftell
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.
Standar POSIX memiliki metode sendiri untuk mendapatkan ukuran file.
Sertakansys/stat.h
tajuk untuk menggunakan fungsi tersebut.
stat(3)
.st_size
propertinya.Catatan : Ini membatasi ukuran 4GB
. Jika bukan Fat32
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);
}
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!
#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);
}
Jika file tersebut adalah
stdin
atau pipa. POSIX, ANSI C tidak akan berfungsi.
Ini akan kembali0
jika file tersebut adalah pipa ataustdin
.Opini : Sebaiknya gunakan standar POSIX . Sebab, memiliki dukungan 64bit.
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;
}
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 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);
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.
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;
}
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
}
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.
Melihat pertanyaan itu, ftell
dengan mudah bisa mendapatkan jumlah byte.
long size = ftell(FILENAME);
printf("total size is %ld bytes",size);
ftell
mengharapkan deskriptor file, bukan nama file, sebagai argumen.
ftell
tidak mengharapkan deskriptor file, FILE*
melainkan. Lihat halaman manual dulu!