Kami berdiskusi di sini tentang mengapa fread dan fwrite mengambil ukuran per anggota dan menghitung serta mengembalikan jumlah anggota yang dibaca / ditulis daripada hanya mengambil buffer dan ukuran. Satu-satunya penggunaan untuk itu yang bisa kami hasilkan adalah jika Anda ingin membaca / menulis array struct yang tidak dapat dibagi secara merata oleh perataan platform dan karenanya telah empuk tetapi itu tidak bisa begitu umum untuk menjamin pilihan ini dalam desain.
Dari FREAD (3) :
Fungsi fread () membaca nmemb elemen data, masing-masing berukuran panjang byte, dari aliran yang ditunjuk oleh aliran, menyimpannya di lokasi yang diberikan oleh ptr.
Fungsi fwrite () menulis elemen nmemb data, masing-masing berukuran panjang byte, ke aliran yang ditunjuk oleh aliran, memperolehnya dari lokasi yang diberikan oleh ptr.
fread () dan fwrite () mengembalikan jumlah item yang berhasil dibaca atau ditulis (yaitu, bukan jumlah karakter). Jika terjadi kesalahan, atau akhir file tercapai, nilai yang dikembalikan adalah hitungan item pendek (atau nol).
Jawaban:
Ini didasarkan pada bagaimana fread diterapkan.
Spesifikasi UNIX Tunggal mengatakan
fgetc juga memiliki catatan ini:
Tentu saja, ini mendahului pengkodean karakter byte variabel yang mewah seperti UTF-8.
SUS mencatat bahwa ini sebenarnya diambil dari dokumen ISO C.
sumber
Perbedaan fread (buf, 1000, 1, stream) dan fread (buf, 1, 1000, stream) adalah, dalam kasus pertama Anda hanya mendapatkan satu potongan 1000 byte atau nuthin, jika file lebih kecil dan di kasus kedua Anda mendapatkan semua yang ada di file kurang dari dan hingga 1000 byte.
sumber
Ini adalah spekulasi murni, namun di masa lalu (Beberapa masih ada) banyak sistem file bukanlah aliran byte sederhana pada hard drive.
Banyak sistem file yang berbasiskan catatan, sehingga untuk memenuhi sistem file tersebut dengan cara yang efisien, Anda harus menentukan jumlah item ("catatan"), yang memungkinkan fwrite / fread untuk beroperasi pada penyimpanan sebagai catatan, bukan hanya aliran byte.
sumber
Di sini, izinkan saya memperbaiki fungsi tersebut:
Adapun alasan untuk parameter ke
fread()
/fwrite()
, saya telah kehilangan salinan K&R saya sejak lama jadi saya hanya bisa menebak. Saya pikir jawaban yang mungkin adalah bahwa Kernighan dan Ritchie mungkin hanya berpikir bahwa melakukan I / O biner akan paling alami dilakukan pada array objek. Juga, mereka mungkin berpikir bahwa blok I / O akan lebih cepat / lebih mudah untuk diimplementasikan atau apapun pada beberapa arsitektur.Meskipun standar C menentukan itu
fread()
danfwrite()
diimplementasikan dalam istilahfgetc()
danfputc()
, ingatlah bahwa standar muncul lama setelah C didefinisikan oleh K&R dan bahwa hal-hal yang ditentukan dalam standar mungkin tidak ada dalam gagasan perancang asli. Bahkan mungkin saja hal-hal yang dikatakan dalam "The C Programming Language" K & R mungkin tidak sama dengan saat bahasa pertama kali dirancang.Terakhir, inilah yang dikatakan PJ Plauger tentang
fread()
"The Standard C Library":Pada dasarnya, dia mengatakan bahwa
fread()
antarmuka rusak. Karenafwrite()
dia mencatat bahwa, "Kesalahan penulisan umumnya jarang, jadi ini bukan kekurangan utama" - pernyataan yang tidak saya setujui.sumber
fread(buf, size*n, 1, stream);
Jika pembacaan yang tidak lengkap adalah kondisi kesalahan, lebih mudah untuk mengaturfread
agar hanya mengembalikan 0 atau 1 daripada jumlah byte yang dibaca. Kemudian Anda dapat melakukan hal-hal sepertiif (!fread(...))
daripada harus membandingkan hasil dengan jumlah byte yang diminta (yang memerlukan kode C ekstra dan kode mesin tambahan).Kemungkinan itu kembali ke cara file I / O diimplementasikan. (dahulu kala) Mungkin lebih cepat untuk menulis / membaca ke file dalam blok kemudian menulis semuanya sekaligus.
sumber
Memiliki argumen terpisah untuk ukuran dan jumlah dapat bermanfaat pada implementasi yang dapat menghindari pembacaan catatan parsial apa pun. Jika seseorang menggunakan pembacaan byte tunggal dari sesuatu seperti pipa, bahkan jika seseorang menggunakan data format tetap, ia harus memungkinkan kemungkinan rekaman terbagi menjadi dua pembacaan. Jika sebaliknya dapat meminta misalnya pembacaan non-pemblokiran hingga 40 catatan masing-masing 10 byte ketika ada 293 byte tersedia, dan memiliki sistem mengembalikan 290 byte (29 seluruh catatan) sementara meninggalkan 3 byte siap untuk pembacaan berikutnya, itu akan jauh lebih nyaman.
Saya tidak tahu sejauh mana implementasi fread dapat menangani semantik seperti itu, tetapi mereka pasti bisa berguna pada implementasi yang menjanjikan untuk mendukungnya.
sumber
fread(buffer, 10000, 2, stdin)
dan pengguna mengetik newline-ctrl-D setelah mengetik 18.000 byte, alangkah baiknya jika fungsi tersebut dapat mengembalikan 10.000 byte pertama sementara sisanya 8.000 menunggu untuk permintaan baca yang lebih kecil di masa mendatang, tetapi apakah ada implementasi apapun yang akan terjadi? Di mana 8.000 byte akan disimpan sambil menunggu permintaan di masa mendatang?size
lebih dari 1, yah ... Sebagai catatan, mungkin juga ada ioctl atau omong kosong lainnya yang dapat Anda terapkan ke aliran untuk membuatnya berperilaku berbeda, saya belum mendalami itu.fread
pekerjaan seperti yang Anda jelaskan pada aliran tersebut akan berguna jika ada beberapa cara untuk mengidentifikasi aliran yang berfungsi dengan cara tersebut.Saya pikir itu karena C kekurangan fungsi overloading. Jika ada, ukuran akan menjadi mubazir. Tetapi di C Anda tidak dapat menentukan ukuran elemen array, Anda harus menentukannya.
Pertimbangkan ini:
Jika fwrite jumlah byte yang diterima, Anda dapat menulis sebagai berikut:
Tapi itu tidak efisien. Anda akan memiliki ukuran (int) kali lebih banyak panggilan sistem.
Hal lain yang harus dipertimbangkan adalah Anda biasanya tidak ingin bagian dari elemen array ditulis ke file. Anda ingin keseluruhan integer atau tidak sama sekali. fwrite mengembalikan sejumlah elemen yang berhasil ditulis. Jadi jika Anda menemukan bahwa hanya 2 byte rendah dari sebuah elemen yang ditulis, apa yang akan Anda lakukan?
Pada beberapa sistem (karena penyelarasan) Anda tidak dapat mengakses satu byte integer tanpa membuat salinan dan pergeseran.
sumber