Search…

Tìm Hiểu về fstream

07/09/20206 min read
Kiến thức về file là một trong những kiến thức quan trọng đối với các lập trình viên. Bài viết này trình bày chi tiết về 2 loại file là file nhị phân và file text, cũng như các kỹ thuật thao tác với file thông qua thư viện fstream.

Kiến thức về file là một trong những kiến thức quan trọng, bài viết này trình bày chi tiết về 2 loại file là file nhị phân và file text, cũng như các kỹ thuật thao tác với file thông qua thư viện fstream.

File nhị phân

Khái niệm

File nhị phân (hay binary file) là một tập tin máy tính, có thể chứa bất kỳ dạng dữ liệu nào và được mã hóa dưới dạng nhị phân để lưu trữ trong máy tính.

Cấu trúc

  • Tập tin nhị phân thường được coi là một chuỗi các byte (8 bit).
  • Có các loại tập tin nhị phân có phần header, chứa thông tin để quy định thêm các thông tin - cấu trúc dữ liệu trong file nhị phân đó.

Ứng dụng

Máy tính chỉ hiểu được mã máy (machine code còn gọi là machine language), do đó mọi dữ liệu muốn được máy tính hiểu đều phải chuyển về dạng nhị phân.

Các file nhị phân hay gặp nhất là dạng execute file (ví dụ định dạng .exe trên Windows, …). File nhị phân có thể lưu trữ được nhiều dạng dữ liệu như file text, file nhạc, file ảnh, …

File văn bản

Khái niệm

File văn bản là một tên gọi chung cho các dạng file lưu trữ dữ liệu dưới dạng ký tự, ví dụ như file text (.txt) hoặc các file lưu trữ mã nguồn (.cpp, .cs, .java).

Cấu trúc

File văn bản có cấu trúc gồm nhiều record. Mỗi một record trong file text được kết thúc bằng ký tự newline character (là ký tự \n hoặc \r\n).

Ứng dụng

File văn bản dùng để lưu trữ dữ liệu dạng ký tự, một số định dạng file văn bản có thể đọc dữ liệu trực tiếp như là file .txt.

Thao tác file với fstream

Thao tác với file gồm 3 giai đoạn:

MỞ FILE → ĐỌC HOẶC GHI DỮ LIỆU → ĐÓNG FILE.

Mở file

Để thao tác với file cần sử dụng thư viện #include <fstream>, đây là thư viện C++ chuẩn nên các đối tượng và hàm được đóng gói trong namespace std.

#include <fstream>
using namespace std;

int main() {
    const char* filePath = "D://file.txt";
    ios_base::openmode mod = ios::in;
   
    fstream f;
    f.open(filePath, mod);

    // TODO:

    return 0;
}

Để mở một file, dùng phương thức open sau:

f.open(filePath, mod);

Trong đó:

  • filePath có kiểu dữ liệu là const char*, là đường dẫn đến file cần mở.
  • mod là chế độ mở file, có một số chế độ như sau:
MOB CHỨC NĂNG
ios::in Mở file để đọc.
ios::out Mở file có sẵn để ghi
ios::binary Mở file ở chế độ nhị phân.
ios:ate Mở file và đặt con trỏ file vào cuối file.
ios::app Mở file và ghi dữ liệu vào cuối file. Nếu file không tồn tại thì tạo file mới.
ios::trunc Chế độ mở file, xóa bỏ hoàn toàn nội dung trong file được mở.

Đọc và ghi dữ liệu với định dạng file nhị phân

Khi mở file mà không ghi rõ chế độ mở file, trình biên dịch sẽ chuyển về chế độ mở file text. Vì vậy, khi muốn mở ở chế độ binary, cần phải ghi rõ mod là ios::binary.

Mở file dưới chế độ binary nghĩa là đọc thông tin theo dạng nhị phân, sử dụng hàm write và read để đọc và ghi file dưới dạng binary.

Đọc dữ liệu từ file sử dụng read

f.read(address, size);

Trong đó:

  • address: Kiểu dữ liệu char*, là địa chỉ mà dữ liệu sẽ lưu vào sau khi đọc lên.
  • size: Kiểu dữ liệu int, là số lượng byte cần đọc từ file.

Ghi dữ liệu vào file sử dụng write

f.write(address, size);

Trong đó:

  • address: Kiểu dữ liệu char*, là địa chỉ vùng nhớ của dữ liệu được lưu vào file.
  • size: Kiểu dữ liệu int, là số lượng byte cần ghi vào file.

Lưu ý:

  • size là kích thước mà vùng nhớ chứa dữ liệu của quá trình đọc hay ghi.

Ví dụ:

#include <fstream>
using namespace std;

int main()
{
	char data[100];

	fstream f;
	f.open("D://text.txt", ios::in | ios::binary);
	if (!f)
		return 1;

	f.read(data, sizeof(data));
	f.close();

	return 0;
}

Đọc và ghi dữ liệu với định dạng file text

Sau khi mở file, tiến hành đọc và ghi file bằng operator >><<.

Đọc file

f >> data;

Trong đó:

  • f:  Kiểu dữ liệu fstream, là tên biến file.
  • data: là tên biến lưu trữ dữ liệu cần đọc từ file.

Lưu ý:

  • data: là tên biến để lưu trữ dữ liệu, có thể có các kiểu như int, float, long, char, ... (nhóm kiểu dữ liệu primitive).
  • Khi dữ liệu được đọc có kiểu khác với biến dữ liệu được lưu trữ.
    • Biến lưu trữ dữ liệu kiểu số không đọc vào kiểu kí tự.
    • Biến lưu trữ dữ liệu kiểu số được tự động chuyển kiểu qua lại giữa các kiểu (float sang int, int sang float) bằng cơ chế chuyển kiểu ngầm định.

Ghi file

f << data;

Trong đó:

  • f:  Kiểu dữ liệu fstream, là tên biến file.
  • data: là tên biến lưu trữ dữ liệu cần ghi vào file.

Lưu ý:

  • Thư viện fstream hỗ trợ ghi dữ liệu char, int, long, ... (nhóm dữ liệu primitive), không hỗ trợ ghi kiểu dữ liệu mở rộng (struct, class, ...).

* Ngoài việc sử dụng operator, có thể tìm hiểu thêm việc sử dụng hàm get và hàm put để lấy thông tin từ file.

Đóng file

Sau khi thao tác với file, đóng file bằng phương thức:

f.close()

Đóng file giúp bảo toàn được dữ liệu đang tiến hành lưu trữ. Đồng thời tránh khỏi một số lỗi không đáng có như 2 thread cùng mở 1 file.

Các ví dụ

Đọc dữ liệu

Thực hiện đọc dữ liệu từ 2 file text, và đọc dữ liệu có các kiểu khác nhau trong cùng một file text.

Trong ví dụ này, có 2 file text:

  • IntroUniversity.txt: lưu trữ tên trường đại học của sinh viên.
  • StorageStudentInfo.txt: lưu thông tin sinh viên học tại trường đó, gồm tên và mã số sinh viên.

File IntroUniversity.txt:

University of Information Technology

File StorageStudentInfo.txt:

Trung	10
Nam	4
Bac	8

Mã nguồn thực thi:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

void printStudentInfo(string studentName[], int studentID[], int numberOfStudents)
{
	for (int i = 0; i < numberOfStudents; ++i)
	{
		cout << studentID[i] << "\t" << studentName[i] << endl;
	}
}

int main()
{
	fstream fs;
	string	nameOfUniversity;
	string	nameOfStudents[3];
	int	idOfStudents[3];

	// Đoạn mã đọc thông tin trường đại học.
	fs.open("IntroUniversity.txt");
	if (!fs)
		return -1;
fs >> nameOfUniversity; cout << nameOfUniversity << endl; fs.close(); // Đoạn mã đọc thông tin sinh viên. fs.open("StorageStudentInfo.txt"); if (!fs) return -1; int index = 0; while (fs) { fs >> nameOfStudents[index] // Đọc thông tin sinh viên từ file. >> idOfStudents[index]; index++; } fs.close(); printStudentInfo(nameOfStudents, idOfStudents, 3); return 0; }

Ghi dữ liệu

#include <fstream>
using namespace std;

int main()
{
	fstream f;
	// Ghi dữ liệu vào file
	int numberData = 1024;

	f.open("text.txt");
	f << numberData;
	f.close();
	return 0;
}
IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024