Saya pada dasarnya mencari versi C ++ dari fdopen (). Saya melakukan sedikit penelitian tentang ini dan ini adalah salah satu hal yang tampaknya mudah, tetapi ternyata sangat rumit. Apakah saya melewatkan sesuatu dalam keyakinan ini (yaitu sangat mudah)? Jika tidak, apakah ada perpustakaan yang bagus di luar sana untuk menangani ini?
EDIT: Memindahkan solusi contoh saya ke jawaban terpisah.
c++
posix
fstream
file-descriptor
BD di Rivenhill
sumber
sumber
mmap
file tersebut dan mengekspos isinya sebagai byte array.Jawaban:
Dari jawaban yang diberikan oleh Éric Malenfant:
Berdasarkan pengamatan di atas dan penelitian saya di bawah ini ada kode yang berfungsi dalam dua varian; satu untuk libstdc ++ dan satu lagi untuk Microsoft Visual C ++.
libstdc ++
Ada
__gnu_cxx::stdio_filebuf
template kelas non-standar yang mewarisistd::basic_streambuf
dan memiliki konstruktor berikutdengan deskripsi Konstruktor ini mengaitkan buffer aliran file dengan deskriptor file POSIX yang terbuka.
Kami membuatnya melalui pegangan POSIX (baris 1) dan kemudian kami meneruskannya ke konstruktor istream sebagai basic_streambuf (baris 2):
Microsoft Visual C ++
Dulu ada versi non-standar dari konstruktor ifstream yang mengambil deskriptor file POSIX tetapi tidak ada baik dari dokumen saat ini maupun dari kode. Ada versi non-standar lain dari konstruktor ifstream yang menggunakan FILE *
dan tidak didokumentasikan (saya bahkan tidak dapat menemukan dokumentasi lama yang akan menampilkannya). Kami menyebutnya (baris 1) dengan parameter yang merupakan hasil dari pemanggilan _fdopen untuk mendapatkan C stream FILE * dari pegangan file POSIX.
sumber
std::cout
implementasi adalah ide yang bagus. Saya bertanya-tanya apa perbedaan antarastdio_filebuf
danstdio_sync_filebuf
?AFAIK, tidak ada cara untuk melakukan ini dalam C ++ standar. Bergantung pada platform Anda, implementasi pustaka standar Anda mungkin menawarkan (sebagai ekstensi nonstandar) konstruktor fstream yang mengambil deskriptor file (Ini adalah kasus untuk libstdc ++, IIRC) atau a
FILE*
sebagai masukan.Alternatif lain adalah dengan menggunakan perangkat boost :: iostreams :: file_descriptor , yang dapat Anda bungkus dalam boost :: iostreams :: stream jika Anda ingin memiliki antarmuka std :: stream.
sumber
Ada kemungkinan besar kompiler Anda menawarkan konstruktor fstream berbasis FILE, meskipun itu non-standar. Sebagai contoh:
Tapi sejauh yang saya tahu, tidak ada cara portabel untuk melakukan ini.
sumber
Bagian dari motivasi asli (tidak disebutkan) dari pertanyaan ini adalah memiliki kemampuan untuk melewatkan data baik di antara program atau di antara dua bagian program pengujian menggunakan file sementara yang dibuat dengan aman, tetapi tmpnam () memberikan peringatan di gcc, jadi saya ingin untuk menggunakan mkstemp () sebagai gantinya. Berikut adalah program tes yang saya tulis berdasarkan jawaban yang diberikan oleh Éric Malenfant tetapi menggunakan mkstemp () daripada fdopen (); ini berfungsi pada sistem Ubuntu saya dengan pustaka Boost diinstal:
sumber
Sebenarnya cukup mudah. Nicolai M. Josuttis telah merilis
fdstream
dalam hubungannya dengan bukunya The C ++ Standard Library - A Tutorial and Reference . Anda dapat menemukan implementasi 184 baris di sini .sumber
Saya telah mencoba solusi yang diusulkan di atas untuk libstdc ++ oleh Piotr Dobrogost, dan menemukan bahwa itu memiliki cacat yang menyakitkan: Karena kurangnya konstruktor pemindahan yang tepat untuk istream, sangat sulit untuk mengeluarkan objek istream yang baru dibangun dari fungsi pembuatan . Masalah lain dengan itu adalah kebocoran objek FILE (bahkan dianggap bukan deskriptor file posix yang mendasarinya). Berikut solusi alternatif yang menghindari masalah ini:
Panggilan ke posix_fadvise () mendemonstrasikan penggunaan potensial. Perhatikan juga bahwa contoh tersebut menggunakan static_assert dan yang menggunakan C ++ 11, selain itu seharusnya dibuat dengan baik dalam mode C ++ 03.
sumber
Pemahaman saya adalah bahwa tidak ada hubungan dengan penunjuk FILE atau deskriptor file dalam model objek C ++ iostream untuk menjaga agar kode tetap portabel.
Konon, saya melihat beberapa tempat merujuk ke mds-utils atau boost untuk membantu menjembatani celah itu.
sumber