соотношение между размером текста и положением в файле - PullRequest
0 голосов
/ 28 апреля 2018

предположим, что у нас есть следующий текстовый файл 'badpoem.txt', который содержит следующие предложения

Oranges and lemons,
Pineapples and tea.
Orangutans and monkeys,
Dragonflys or fleas.

я определил размер для каждого предложения в байтах

 whos
  Name        Size            Bytes  Class     Attributes

  ans         1x1                 8  double              
  fid         1x1                 8  double              
  tline1      1x19               38  char                
  tline2      1x19               38  char                
  tline3      1x23               46  char   

где tline1, tline2 и tline3 - соответствующие тексты, теперь, когда я трижды открыл файл и прочитал текст, я проверил текущую позицию файлов, и вот результат для первого

fid = fopen('badpoem.txt');
ftell(fid)

ans = 0

он открывается, так что все нормально, теперь прочитайте первый текст

tline1 = fgetl(fid)  % read the first line
ftell(fid)

tline1 =

    'Oranges and lemons,'


ans =

    21
 now lets read second file
tline2 = fgetl(fid)
ftell(fid)

tline2 =

    'Pineapples and tea.'


ans =

    42            

и, наконец, последний

tline3 = fgetl(fid)
ftell(fid)

tline3 =

    'Orangutans and monkeys,'


ans =

    67

есть ли связь между размером текста и позицией? заранее спасибо

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Очень хороший вопрос, действительно. На самом деле, я думаю, что вас смущает тот факт, что вы сталкиваетесь с множеством разных проблем, смешанных вместе. Давайте проанализируем их один за другим.


1) Формат файла TXT в Windows

Обычно (азиатские локали и расширенные текстовые редакторы являются распространенным исключением), текстовые файлы под Windows кодируются ANSI (где ANSI - это общий способ ссылки на кодировки ISO/IEC 8859). В этой структуре кодирования с двоичной точки зрения каждый символ представлен одним байтом. Если вы откроете такие TXT файлы с помощью Notepad и вставите в них несколько китайских идеограмм, это сообщение вы увидите при попытке сохранить изменения:

Этот файл содержит символы в формате Unicode, которые будут потеряны, если Вы сохраняете этот файл как текстовый файл в кодировке ANSI. Сохранить юникод информация, нажмите Отмена ниже, а затем выберите один из Unicode вариант из раскрывающегося списка Кодировка. Продолжить?

2) Разделители строк под Windows

Как уже отмечали другие пользователи, в Windows разрыв строки по умолчанию представлен комбинацией двух символов: возврат каретки (более известный как \r или 0xD) и перевод строки (более известный как \n или 0xA). Вот пример на основе вашего текста:

Oranges and lemons,\r\nPineapples and tea.\r\nOrangutans and monkeys,\r\nDragonflys or fleas.

Этого не происходит с другими операционными системами, такими как Linux и MacOS, в которых поддерживаются только переводы строк:

Oranges and lemons,\nPineapples and tea.\nOrangutans and monkeys,\nDragonflys or fleas.

3) Хранение строк под Matlab

Matlab хранит символы в памяти как Unicode 16-битные целые числа без знака, занимающие по два байта каждый. Это не зависит от текущей кодировки Matlab (которая может быть получена с помощью команды feature('DefaultCharacterSet') и по умолчанию соответствует текущей кодировке операционной системы).

4) Функция fgetl

В соответствии с официальной документацией , функция fgetl считывает одну строку из файла (сигнально, допустимый дескриптор файла), исключая разрывы строк. Это означает, что Matlab читает всю строку, включая все символы разрыва строки, но они обрезаются из выходной строки, возвращаемой функцией.

Разница между fgetl и fgets заключается в том, что первый обрезает разрыв строки, а второй - нет.


Все это, как говорится, давайте шаг за шагом проанализируем, что происходит в вашем коде. Сначала вы открываете файл, и указатель помещается в начало потока:

fid = fopen('data.txt','r');
ftell(fid) % 0

Затем вы читаете первую строку:

tline1 = fgetl(fid)
ftell(fid) % 21

Строка содержит 19 символов (размер, который вы получаете из таблицы whos), которые на стороне памяти хранятся с использованием 38 байтов из-за Unicode. Вызов ftell отображает число 21, потому что fgetl читает всю строку, которая включает два символа разрыва строки, которые были обрезаны из вывода (0 + 19 + 2 = 21).

Затем вы читаете вторую строку:

tline2 = fgetl(fid)
ftell(fid) % 42

Строка содержит 19 символов, которые на стороне памяти сохраняются с использованием 38 байтов. Вызов ftell отображает число 42, потому что fgetl читает всю строку, которая включает в себя два символа разрыва строки, которые были обрезаны на выходе. Из предыдущего смещения 21 + 19 + 2 = 42.

Наконец, вы читаете третью строку:

tline3 = fgetl(fid)
ftell(fid) % 67

Строка содержит 23 символов, которые на стороне памяти хранятся с использованием 46 байтов. Вызов ftell отображает число 67, потому что fgetl читает всю строку, которая включает в себя два символа разрыва строки, которые были обрезаны на выходе. Из предыдущего смещения 42 + 23 + 2 = 67.

0 голосов
/ 28 апреля 2018

Для текстовых файлов Windows добавляет два символа в конце каждой строки, другие системы добавляют один. Matlab, при чтении строки пропускает их в возвращаемой строке, но поскольку Windows добавляет два вместо одного, вы получаете значения положения для Windows, отличные от показанных в примере Matlab здесь:

https://www.mathworks.com/help/matlab/ref/ftell.html

Строки символов сохраняются в файлах, используя один байт для каждого символа, но сохраняются в памяти Matlab как 16-битные слова или 2 байта для каждого символа, что удваивает видимый размер строк символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...