ฉันจะหาขนาดของไฟล์เป็นไบต์ได้อย่างไร
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* file
ทำไมไม่FILE* file
? -1
ฉันจะหาขนาดของไฟล์เป็นไบต์ได้อย่างไร
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* file
ทำไมไม่FILE* file
? -1
คำตอบ:
ขึ้นอยู่กับรหัสของ 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;
}
การเปลี่ยนแปลง:
const char
ทำชื่อไฟล์อาร์กิวเมนต์struct stat
คำจำกัดความซึ่งไม่มีชื่อตัวแปร-1
ข้อผิดพลาดแทน0
ซึ่งจะคลุมเครือสำหรับไฟล์ว่าง off_t
เป็นประเภทที่เซ็นชื่อดังนั้นจึงเป็นไปได้หากคุณต้องการfsize()
พิมพ์ข้อความผิดพลาดคุณสามารถใช้สิ่งนี้:
#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;
}
ในระบบ 32 บิตคุณควรรวบรวมสิ่งนี้ด้วยตัวเลือก-D_FILE_OFFSET_BITS=64
มิฉะนั้นoff_t
จะเก็บค่าได้สูงสุด 2 GB ดูส่วน "การใช้ LFS" ของการสนับสนุนไฟล์ขนาดใหญ่ใน Linuxสำหรับรายละเอียด
fseek
+ ftell
ตามที่ Derek เสนอ
fseek
+ ftell
ตามที่ Derek เสนอ ไม่C มาตรฐานระบุว่าการfseek()
ไปSEEK_END
ที่ไฟล์ไบนารีนั้นเป็นพฤติกรรมที่ไม่ได้กำหนด 7.19.9.2 fseek
ฟังก์ชั่น ... สตรีมแบบไบนารีไม่จำเป็นต้องรองรับการfseek
โทรที่มีความหมายซึ่งมีค่าเท่ากับSEEK_END
และตามที่ระบุไว้ด้านล่างซึ่งมาจากเชิงอรรถ 234 ในหน้า 267 ของการเชื่อมโยง C มาตรฐานและที่เฉพาะป้ายfseek
ไปSEEK_END
ในกระแสไบนารีเป็นพฤติกรรมที่ไม่ได้กำหนด .
int
อย่าใช้ ไฟล์ที่มีขนาดเกิน 2 กิกะไบต์นั้นถือได้ว่าเป็นเรื่องสกปรกในทุกวันนี้
unsigned int
อย่าใช้ ไฟล์ที่มีขนาดเกิน 4 กิกะไบต์นั้นเป็นเรื่องธรรมดาเนื่องจากฝุ่นสกปรกเล็กน้อยทั่วไป
IIRC ไลบรารีมาตรฐานกำหนดoff_t
เป็นจำนวนเต็ม 64 บิตที่ไม่ได้ลงชื่อซึ่งเป็นสิ่งที่ทุกคนควรใช้ เราสามารถกำหนดใหม่ให้เป็น 128 บิตในไม่กี่ปีเมื่อเราเริ่มมี 16 exabyte ไฟล์ที่แขวนอยู่รอบ ๆ
หากคุณใช้ Windows คุณควรใช้GetFileSizeExซึ่งใช้จำนวนเต็ม 64 บิตที่ได้รับการเซ็นชื่อดังนั้นพวกเขาจะเริ่มตีปัญหาด้วยไฟล์ exabyte 8 ไฟล์ โง่เขลา Microsoft! :-)
วิธีการแก้ปัญหาของ Matt ควรทำงานยกเว้นว่าเป็น C ++ แทน C และการบอกเริ่มต้นไม่ควรจำเป็น
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;
}
แก้ไขรั้งสำหรับคุณเช่นกัน ;)
อัปเดต: นี่ไม่ใช่ทางออกที่ดีที่สุดจริงๆ มัน จำกัด ให้ไฟล์ 4GB บน Windows และเป็นไปได้ช้ากว่าเพียงแค่ใช้โทรแพลตฟอร์มที่เฉพาะเจาะจงเช่นหรือGetFileSizeEx
stat64
long int
การร่ายไม่ได้ปรับปรุงช่วงตามที่ จำกัด ไว้โดยฟังก์ชั่น ส่งคืน -1 เมื่อเกิดข้อผิดพลาดและทำให้สับสนกับการร่าย ขอแนะนำให้ส่งกลับชนิดเดียวกับ ftell()
(unsigned long)
ftell()
fsize()
ftell()
** อย่าทำอย่างนี้ ( เพราะอะไร ):
การอ้างอิงเอกสารมาตรฐาน C99 ที่ฉันพบทางออนไลน์: "การตั้งค่าตัวบ่งชี้ตำแหน่งไฟล์เป็นจุดสิ้นสุดไฟล์เช่นเดียวกับ
fseek(file, 0, SEEK_END)
พฤติกรรมที่ไม่ได้กำหนดสำหรับสตรีมไบนารี่ (เนื่องจากอักขระ null ที่เป็นไปได้ต่อท้าย) หรือสตรีมใด ๆ ที่ไม่สิ้นสุดอย่างมั่นใจในสถานะการเปลี่ยนครั้งแรก **
เปลี่ยนนิยามเป็น int เพื่อให้สามารถส่งข้อความแสดงข้อผิดพลาดจากนั้นใช้fseek()
และftell()
เพื่อกำหนดขนาดไฟล์
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
และftello
(หรือfseek
และftell
หากคุณติดค้างอยู่โดยไม่มีข้อ จำกัด ในอดีตและมีความสุขกับการ จำกัด ขนาดไฟล์ที่คุณสามารถทำงานได้) เป็นวิธีที่ถูกต้องในการกำหนดความยาวของไฟล์ stat
โซลูชันที่ใช้งานไม่ได้กับ "ไฟล์" จำนวนมาก (เช่นอุปกรณ์บล็อก) และไม่สามารถพกพาไปยังระบบที่ไม่ใช่ POSIX-ish
POSIXมาตรฐานมีวิธีการของตัวเองเพื่อให้ได้ขนาดไฟล์
รวมsys/stat.h
ส่วนหัวเพื่อใช้ฟังก์ชั่น
stat(3)
รับสถิติไฟล์โดยใช้st_size
ทรัพย์สินหมายเหตุ : มัน จำกัด ขนาด4GB
ไว้ที่ หากไม่ใช่Fat32
ระบบไฟล์ให้ใช้เวอร์ชัน 64 บิต!
#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ไม่ได้โดยตรงให้วิธีการที่จะกำหนดความยาวของไฟล์
เราจะต้องใช้ความคิดของเรา สำหรับตอนนี้เราจะใช้วิธีการค้นหา!
#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);
}
หากไฟล์เป็น
stdin
หรือไปป์ POSIX, ANSI Cจะไม่ทำงาน
มันจะไปกลับมาหากไฟล์ที่เป็นท่อหรือ0
stdin
ความคิดเห็น : คุณควรใช้มาตรฐานPOSIXแทน เพราะมันรองรับ 64 บิต
struct _stat64
และ__stat64()
สำหรับ _Windows
และถ้าคุณกำลังสร้างแอพ Windows ให้ใช้GetFileSizeEx API เนื่องจากไฟล์ I / O ของ CRT นั้นยุ่งโดยเฉพาะอย่างยิ่งในการกำหนดความยาวของไฟล์เนื่องจากลักษณะเฉพาะในการนำเสนอไฟล์บนระบบต่าง ๆ ;)
หากคุณพอใจกับการใช้ไลบรารี 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;
}
การค้นหาอย่างรวดเร็วใน Google พบวิธีการใช้ fseek และ ftellและเธรดกับคำถามนี้พร้อมคำตอบที่ไม่สามารถทำได้ด้วย C ในอีกวิธีหนึ่ง
คุณสามารถใช้ไลบรารี่แบบพกพาเช่นNSPR ( ไลบรารี่ที่ให้พลัง Firefox) หรือตรวจสอบการนำไปใช้ (ค่อนข้างลำบาก)
ฉันใช้รหัสชุดนี้เพื่อหาความยาวของไฟล์
//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);
ลองนี้ -
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
สิ่งนี้ทำก่อนอื่นให้หาจุดสิ้นสุดของไฟล์ จากนั้นรายงานว่าตัวชี้ไฟล์อยู่ที่ใด สุดท้าย (เป็นทางเลือก) มันจะย้อนกลับไปที่จุดเริ่มต้นของไฟล์ โปรดทราบว่าfp
ควรเป็นสตรีมไบนารี
file_size มีจำนวนไบต์ที่ไฟล์มี โปรดทราบว่าเนื่องจาก (ตาม climits.h) ประเภทยาวที่ไม่ได้ลงชื่อจะถูก จำกัด ที่ 4294967295 ไบต์ (4 กิกะไบต์) คุณจะต้องค้นหาตัวแปรชนิดอื่นหากคุณมีแนวโน้มที่จะจัดการกับไฟล์ที่มีขนาดใหญ่กว่านั้น
ftell
จะไม่ส่งคืนตัวแทนค่าของจำนวนไบต์ที่สามารถอ่านได้จากไฟล์
stdio.h
ฉันมีฟังก์ชั่นที่ทำงานได้ดีมีเพียง ฉันชอบมันมากและใช้งานได้ดีและค่อนข้างกระชับ:
size_t fsize(FILE *File) {
size_t FSZ;
fseek(File, 0, 2);
FSZ = ftell(File);
rewind(File);
return FSZ;
}
นี่คือฟังก์ชั่นที่เรียบง่ายและสะอาดที่จะคืนค่าขนาดไฟล์
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
}
คุณสามารถเปิดไฟล์ไปที่ 0 offset เทียบกับด้านล่างของไฟล์ด้วย
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
ค่าที่ส่งคืนจาก fseek คือขนาดของไฟล์
ฉันไม่ได้ใช้รหัสใน C เป็นเวลานาน แต่ฉันคิดว่ามันควรจะใช้ได้
เมื่อดูที่คำถามftell
สามารถรับจำนวนไบต์ได้อย่างง่ายดาย
long size = ftell(FILENAME);
printf("total size is %ld bytes",size);
ftell
คาดว่า file descriptor ไม่ใช่ชื่อไฟล์เป็นอาร์กิวเมนต์
ftell
ไม่ไม่คาดว่าจะเป็นตัวให้คำอธิบายไฟล์ แต่คาดว่าจะเป็นFILE*
แทน ดูหน้าคนแรก!
fseek()
ก่อนเพื่อค้นหาจุดสิ้นสุดของไฟล์และยังftell()
คาดว่า a FILE *
ไม่ใช่สายอักขระ คุณจะได้รับการตอบรับอย่างดี