Обход файла в цикле от конца к началу

Здравствуйте! Подскажите пожалуйста, кто знает. Как обойти файл вне зависимости от его размера?
В моем коде я использую переменную типа лонг. Но если файл например будет 10 Гб, то работать не будет. Как правильно?

char c;//переменная для хранения одного байта считанного из файла
	for (long i = -1; i > -(length + 1); i--) {//цикл обхода файла от конца к началу
		file.seekg(i, ios::end);//установка указателя чтения файла на позицию i с конца файла
		file.get(c);//чтение байта из файла в переменную c
		cout << с<<endl;//вывод в консоль байта
	}

Наверно надо long long или int64_t.

А если принципиально? Ну, вот, чтобы не использовать размер файла.
Можно циклом whille? Или do? По условию, что не начало файла. Так можно?

Обычно читают с начала и до конца (.eof()), тогда всё просто.

Наоборот наверно можно с ios::cur в seekg, и открывать файл изначально в конце fstream::open - C++ Reference, ну или после открытия seekg с ios::end.
Переходить надо сначала на -1 (от конца), потом по -2 (если чтение по 1 байту).
И tellg, чтоб узнать когда начало.

Т.е. while(!tellg)? Так?
Курсоры устанавливать и переходить я понял как. Меня интересует именно условие. Никак не могу поймать правильное)
Когда остановить цикл, после того, как он прочитал первый байт считываемого с конца файла.

tellg позицию возвращает. Так что видимо без !.

Т.е. при while(tellg) в цикле do цикл остановится. (мне ведь из tellg надо ещё считать последний байт, я правильно понял?)

Условие while (file.tellg()) зацикливает на бесконечность)

Так а внутри что?

Ну и проверять же видимо надо либо после seekg, либо отнимать размер прочитанного.

Внутри вот.

char mirror_2 = 's';//переменная для хранения символа из файла(бита)
	int j = 0;//переменая - номер бита, для обхода по битам внутри байта

	//for (long i = -1; i > -(length + 1); i--) 
	int a = -1;
	while (mirror_2 != 'a')//цикл обхода файла от конца к началу
	{
		file.seekg(a, ios::end);//установка указателя чтения файла на позицию i с конца файла
		mirror_2 = 'a';
		file.get(mirror_2);//чтение байта из файла в переменную c

		if (mirror_2 == '0' || mirror_2 == '1') 
		{
			cout << mirror_2;//вывод бита в консоль
		}
		a--;
	}

Я хочу решить задачу по выводу любого количества битов любого размера файла.
Но пока решил только с условием цикла.
Однако будет ошибка тогда, когда исчерпает свой ресурс int
Подскажите пожалуйста, как можно переходить от байта к байту без использования счетчика позиции байта от конца файла (file.seekg(a, ios::end))?

Для этого и придумали 64 бит :kolobokbatya:

Так выше ж было


Как-то так работает:

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

void writeFile() {
  ofstream fs;
  fs.exceptions(ios::failbit | ios::badbit);
  fs.open("example.txt");
  fs << "Hello world!";
}

void readFile() {
  ifstream fs;
  fs.exceptions(ios::failbit | ios::badbit);
  fs.open("example.txt");

  fs.seekg(-1, ios::end);

  char ch;
  while (true) {    
    fs.get(ch);
    cout << ch;

    if (fs.tellg() == 1) {
      break;
    }
    fs.seekg(-2, ios::cur);
  }
}

int main() {
  try {
    writeFile();
    readFile();
  } catch (const ios::failure &exc) {
    cerr << "File I/O error." << endl;
  }

  return 0;
}

read file reverse - Replit

Спасибо. Буду осваивать.

А если переход по одному биту, то -1?

минимальная единица данных, которую можно записать в файл или прочитать из файла - это один байт.
читайте байт и получайте бонусом сразу восемь бит :slight_smile:

Кроме того, даже по одному байту читать/писать - очень часто непозволительная роскошь (если кеширования не будет - будет полчаса 1 мегабайт читать).
Поэтому, если нужно, условно, n байт с конца файла, имеет смысл поставить указатель в файле на позицию ДлинаФайла +1 - n и прочитать в память сразу n байт. Обработать их как надо, поставить указатель на ту же позицию и за одну операцию записать n байт (ну, если нужна запись, конечно).

А если файл 1 Терабайт (чисто теоретически?) Никак длину файла на узнать.

Почему? В 64 бита поместится и петабайт )

Это шутка такая? :wink:
Как можно создать файл в ФС, где размер файла превышает заданную величину?

вот у меня Windows, на диске файловая система NTFS

Лимиты:
Максимальный размер файла: 2^64 байт (16 ЭиБ = 16 Эксбибайт)
Максимум файлов: 4 294 967 295 (2^32−1)

да вроде бы туда и эксабайт
влезет :wink:

char mirror_2;//переменная для хранения символа из файла(бита)


	for (int64_t i = -1; i > -(length + 1); i--) {//цикл обхода файла от конца к началу
		file.seekg(i, ios::end);//установка указателя чтения файла на позицию i с конца файла
		file.get(mirror_2);//чтение бита из файла в переменную c

		if (mirror_2 == '0' || mirror_2 == '1') {//условие - если символ считанный из файла равен 0 или 1, то идем дальше
			cout << mirror_2;//вывод бита в консоль

Вот в этом коде по одному биту выводится в консоль