Форум программистов, компьютерный форум, киберфорум
Pure Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/25: Рейтинг темы: голосов - 25, средняя оценка - 4.60
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443

Особенности работы с файлами в PureBasic

05.02.2023, 22:45. Показов 5898. Ответов 55
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Столкнулся с такой проблемой.
Надо считать весь контент текстового файла в строковую переменную, но не построчно (так легко), а сразу весь целиком.
Вот работающий код PowerBasic, который выполняет эту работу и демонстрирует считанную строку в месседжбоксе:

PowerBasic
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#COMPILE EXE
 
function pbmain () AS LONG
  Local str_Text As String
  Local lng_File_length As Long
 
  'Считываем весь файл целиком в память.
  Open "C:\test.txt" For Binary As #0
     lng_File_length = LOF(0)
     str_Text = Space$ (lng_File_length)
     Get #0, , str_Text
  Close #0
  msgbox (str_Text)
END function
А как сделать то же самое в PureBasic?
Чем заменить функцию GET, которой нет в PureBasic?
GET [#] filenum&, [RecPos], Var
Если опциональный RecPos опущен, считывание файла начинается с первого байта.

Вот набросал работающую заготовку. Что надо вставить вместо вопросительных знаков?
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
EnableExplicit
 
Define str_Text.s
Define lng_File_length.l
 
; Считываем весь файл целиком в память.
If OpenFile(0, "Test.txt")
    lng_File_length = Lof(0)
    str_Text = Space (lng_File_length)
;   ??????????????????????????????????    
;   ??????????????????????????????????
   CloseFile (0)
EndIf     
  MessageRequester("", str_Text)
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.02.2023, 22:45
Ответы с готовыми решениями:

JApplet: особенности работы с локальными файлами
Если ли какие-то особенности, при работе с файловыми потоками из потомка JApplet? Можно ли писать в локальные файлы из swing-апплета?...

особенности работы ViewState
недавно начал изучать ASP. немного почитал про жизненный цикл и особенности работы ViewState. Возник следующий вопрос: есть страничка: ...

Особенности работы установщика
Здравствуйте. Если я создал установщик, который устанавливает сразу два проекта и в обоих проектах я переопределил метод Install, то...

55
Эксперт по электронике
6494 / 3124 / 331
Регистрация: 28.10.2011
Сообщений: 12,289
Записей в блоге: 7
06.02.2023, 01:33
Лучший ответ Сообщение было отмечено Power_Basic как решение

Решение

Если тест в формате юникода, код по проще
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
EnableExplicit
 
Define str_Text.s
Define lng_File_length.l
 
; Считываем весь файл целиком в память.
If OpenFile(0, "Test.txt")
  lng_File_length = Lof(0)
  str_Text = Space (lng_File_length / 2)
  ReadData(0, @str_Text, StringByteLength(str_Text))
  CloseFile (0)
EndIf     
MessageRequester("", str_Text)
Если в другом формате, его нужно преобразовать в юникод.
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
EnableExplicit
 
Define str_Text.s, *str_Text
Define lng_File_length.l, Format
 
; Считываем весь файл целиком в память.
If OpenFile(0, "Test.txt")
  lng_File_length = Lof(0)
  Format = ReadStringFormat(0)
  *str_Text = AllocateMemory(lng_File_length+2)
  If *str_Text
    ReadData(0, *str_Text, lng_File_length)
    str_Text = PeekS(*str_Text, -1, Format)
    FreeMemory(*str_Text)
  EndIf
  CloseFile (0)
EndIf     
MessageRequester("", str_Text)
1
62 / 60 / 3
Регистрация: 06.11.2010
Сообщений: 184
Записей в блоге: 1
06.02.2023, 14:52
Можно так
PureBasic
1
2
3
4
5
6
#File = 0
If ReadFile(#File, FilePath$)
    Format = ReadStringFormat(#File)
    Text$ = ReadString(#File, Format | #PB_File_IgnoreEOL)
    CloseFile(#File)
EndIf
Но в недавних обсуждениях люди жаловались, что ReadString() медленно работает, Фред обещал исправить. То есть несмотря на флаг "IgnoreEOL" игнорировать конец строки и читать до конца файла, функция продолжает читать в цикле, то есть построчно, хотя можно было тупо использовать алгоритм ReadData(). Но не важно, в общем для мелких текстовых файлов можно так. И кстати это старый пример, сейчас #File не использую, только #PB_Any, так как в какой то момент это перерастает в функцию и используется методом копипасты в крупную программу, а там идентификатор "0" может быть занят, так что сразу пишем правильно.

Как то так:
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
EnableExplicit
 
Global g_Format
 
; https://www.purebasic.fr/english/viewtopic.php?p=478874
XIncludeFile "AutoDetectTextEncoding_Trim.pbi"
 
; Чтение файла в гаджет
Procedure.s OpenFileToGadget(FilePath$)
    Protected length, oFile, bytes, *mem, Text$
    oFile = ReadFile(#PB_Any, FilePath$)
    If oFile
        g_Format = ReadStringFormat(oFile)
        length = Lof(oFile)
        *mem = AllocateMemory(length)
        If *mem
            bytes = ReadData(oFile, *mem, length)
            If bytes
                If g_Format = #PB_Ascii
                    g_Format = dte::detectTextEncodingInBuffer(*mem, bytes, 0)
                    If g_Format = #PB_Ascii
                        Text$ = PeekS(*mem, bytes, #PB_Ascii)
                    Else
                        Text$ = PeekS(*mem, bytes, #PB_UTF8) ; если UTF8 без BOM
                    EndIf
                Else
                    ; тут не уверен, PeekS() поддерживает #PB_Unicode,
                    ; а ReadStringFormat() может дать #PB_UTF16BE, #PB_UTF32, #PB_UTF32BE
                    ; хотя эти форматы не популярны скорее не встретятся, и надо сделать на них игнор
                    Text$ = PeekS(*mem, bytes, g_Format)
                EndIf
            EndIf
                FreeMemory(*mem)
        EndIf
        CloseFile(oFile)
    EndIf
    ProcedureReturn Text$
EndProcedure
 
Define FilePath$ = "C:\2023.01\1.txt"
Debug OpenFileToGadget(FilePath$)
Я взял этот пример из своей программы My_Notepad_Sci, немного скорретировав. Там же в комплекте урезанный "AutoDetectTextEncoding_Trim.pbi". Если формат файла заранее известный, то ко всем этим трюкам прибегать не обязательно. Переменная g_Format глобальная, потому что я использовал это в Scintilla, там при работе с текстом надо знать формат.

Заменил bytes вместо -1, так как тут нет завершение нультерминированной строкой.
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
06.02.2023, 17:13  [ТС]
Цитата Сообщение от locm Посмотреть сообщение
Если тест в формате юникода, код по проще.
Если в другом формате, его нужно преобразовать в юникод.
Большое спасибо!
С вами вообще очень приятно общаться. Подсказываете всегда именно то, что хочет услышать задающий вопрос, а не уводя его в глубины, которые ему вот прямо сейчас совершенно не нужны, поскольку он к ним вот прямо сейчас совершенно не готов.

Цитата Сообщение от AZJIO Посмотреть сообщение
То есть несмотря на флаг "IgnoreEOL" игнорировать конец строки и читать до конца файла, функция продолжает читать в цикле, то есть построчно
Ну тогда мне это не годится. Звучит как партизанщина какая-то

Цитата Сообщение от AZJIO Посмотреть сообщение
Как то так
А вот это как раз пример тех самых глубин, о которых я написал выше

Но в любом случае, спасибо за желание помочь.
0
62 / 60 / 3
Регистрация: 06.11.2010
Сообщений: 184
Записей в блоге: 1
06.02.2023, 17:59
Цитата Сообщение от Power_Basic Посмотреть сообщение
которые ему вот прямо сейчас совершенно не нужны
Цитата Сообщение от Power_Basic Посмотреть сообщение
это как раз пример тех самых глубин
Цитата Сообщение от Power_Basic Посмотреть сообщение
за желание помочь
Хорошо что честно сказано, а то я тогда лучше програмку свою попишу, если всё равно время зря теряю.
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
07.02.2023, 22:27  [ТС]
Цитата Сообщение от locm Посмотреть сообщение
Если в другом формате, его нужно преобразовать в юникод.
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
EnableExplicit
Define str_Text.s, *str_Text
Define lng_File_length.l, Format
; Считываем весь файл целиком в память.
If OpenFile(0, "Test.txt")
  lng_File_length = Lof(0)
  Format = ReadStringFormat(0)
  *str_Text = AllocateMemory(lng_File_length+2)
  If *str_Text
    ReadData(0, *str_Text, lng_File_length)
    str_Text = PeekS(*str_Text, -1, Format)
    FreeMemory(*str_Text)
  EndIf
  CloseFile (0)
EndIf     
MessageRequester("", str_Text)
На самом деле, это очень удобно. Скачиваем и сразу конвертируем в нужный формат "на лету". Профессиональный универсальный подход! Обычно-то я в своих программах на PowerBasic считываю весь файл в одну большую строку как попало, потом "на глазок" смотрю, нормальный получается русский текст или каракули
И если каракули, тогда уже пытаюсь сконвертировать полученную строку в правильный формат.

А зачем в памяти резервируем ещё 2 байта помимо длины строки?

Добавлено через 20 минут
Кажется, я сообразил. Это, наверно, место для метки BOM.
0
Эксперт по электронике
6494 / 3124 / 331
Регистрация: 28.10.2011
Сообщений: 12,289
Записей в блоге: 7
07.02.2023, 22:50
Цитата Сообщение от Power_Basic Посмотреть сообщение
А зачем в памяти резервируем ещё 2 байта помимо длины строки?
В юникоде нультерминированная строка завершается двумя нулями.
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
08.02.2023, 14:24  [ТС]
Цитата Сообщение от locm Посмотреть сообщение
Цитата Сообщение от Power_Basic Посмотреть сообщение
А зачем в памяти резервируем ещё 2 байта помимо длины строки?
В юникоде нультерминированная строка завершается двумя нулями.
На самом деле, это была моя первая гипотеза, но я сам себе не поверил
Что-то в мозгах переклинило


Необычное для меня объявление указателей в PureBasic. Здесь они какие-то всеядные. В PowerBasic вот так делать запрещено:
PureBasic
1
Define *A
Компилятор ругается "Неопределённый тип":
PowerBasic
PureBasic
1
 dim A as pointer  ' !!!!!!!!!!!! ОШИБКА
Можно объявлять указатели на переменные только так:

PowerBasic
PureBasic
1
2
3
  dim A as string pointer
  dim B as long pointer     
  dim C as word pointer
То есть там необходимо ещё при объявлении любого указателя на любую переменную сразу же оговаривать, на какой именно тип переменной он будет указывать, чтобы компилятор наперёд знал, переменная какого именно типа будет храниться по этому адресу.
0
Эксперт по электронике
6494 / 3124 / 331
Регистрация: 28.10.2011
Сообщений: 12,289
Записей в блоге: 7
08.02.2023, 20:13
Цитата Сообщение от Power_Basic Посмотреть сообщение
Необычное для меня объявление указателей в PureBasic.
Это указатель без типа. Просто переменная хранящая адрес.
1
 Аватар для CoderHuligan
1743 / 1008 / 257
Регистрация: 30.06.2015
Сообщений: 5,107
Записей в блоге: 56
09.02.2023, 11:32
Цитата Сообщение от Power_Basic Посмотреть сообщение
Скачиваем и сразу конвертируем в нужный формат "на лету". Профессиональный универсальный подход!
Профессиональный подход всегда НЕ универсален. Скачивать весь файл целиком признак НЕ профессионального подхода. Потому что файл может просто не влезть в ОЗУ, а вы этого и не думали проверить. Обычно файл скачивают частями в буфер определенного размера. Например в Си такой буфер есть на уровне IO функций, поэтому не требуется его создавать явно. То есть, скачивая даже по одному символу, на деле будет производится закачка в целый буфер, а затем посимвольно считываться из этого буфера, а не с диска. Все уже давно придумано и автоматизировано. Неужели в в PureBasic это по другому реализовано?
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
09.02.2023, 15:03  [ТС]
Цитата Сообщение от CoderHuligan Посмотреть сообщение
Профессиональный подход всегда НЕ универсален. Скачивать весь файл целиком признак НЕ профессионального подхода. Потому что файл может просто не влезть в ОЗУ, а вы этого и не думали проверить.
Я не профессионал, я любитель. Пишу программы только для себя любимого, ёмкость ОЗУ своего компьютера я прекрасно знаю. Даже если что-тоне учту, и программа аварийно завершится, большой беды не будет, - буду разбираться, искать ошибку в коде и исправлять её.


Цитата Сообщение от CoderHuligan Посмотреть сообщение
Обычно файл скачивают частями в буфер определенного размера. Например в Си такой буфер есть на уровне IO функций, поэтому не требуется его создавать явно. То есть, скачивая даже по одному символу, на деле будет производится закачка в целый буфер, а затем посимвольно считываться из этого буфера, а не с диска.
Все уже давно придумано и автоматизировано. Неужели в PureBasic это по другому реализовано?
Наверняка, и в PureBasic что-то реализовано в этом направлении. Но я просил именно сразу весь файл в текстовую переменную, мне так нравится, ну вот и получил ровно то, что просил.
1
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,255
Записей в блоге: 4
09.02.2023, 21:02
Вообще это очень неэффективно заводить буфер для байтов файла, затем читать файл в этот буфер, потом создавать строку на основе байт из этого буфера…
Эффективно — это отобразить файл в память. Пара вызовов функций и у вас уже сразу указатель на байты без всяких буферов, промежуточных чтений и строковых конвертаций.

Добавлено через 3 часа 37 минут
Цитата Сообщение от locm Посмотреть сообщение
Это указатель без типа. Просто переменная хранящая адрес.
Как узнать какие данные там хранятся? Через комментарии в коде?
1
Эксперт по электронике
6494 / 3124 / 331
Регистрация: 28.10.2011
Сообщений: 12,289
Записей в блоге: 7
09.02.2023, 21:11
Цитата Сообщение от Замабувараев Посмотреть сообщение
Пара вызовов функций и у вас уже сразу указатель на байты без всяких буферов, промежуточных чтений и строковых конвертаций.
Дополнительный буфер нужен для конвертации кодировки текста.

Без дополнительного буфера первый пример Особенности работы с файлами в PureBasic

Цитата Сообщение от Замабувараев Посмотреть сообщение
Как узнать какие данные там хранятся?
Тип данных все равно не сообщит что хранится по указателю.
Те более что в данном случае тип не нужен. Его можно задать но он ни на что это не повлияет.
1
12 / 12 / 0
Регистрация: 02.07.2014
Сообщений: 106
10.02.2023, 19:03
Для доступа в память по указателю с учётом типа есть бэйсик стиль функции peekX/pokeX и
условно Си стиль. Все простые типы имеют эквивалентные встроенные структуры.
;Structure Unicode
; u.u
;EndStructure
EnableExplicit

Define StrNum.s = "0123456789"

Define *p_u.Unicode = @StrNum
Debug Chr(*p_u\u)

*p_u = *p_u + SizeOf(Unicode)
Debug Chr(*p_u\u)

*p_u = *p_u + (SizeOf(Unicode)*8)
Debug Chr(*p_u\u)
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
13.02.2023, 15:11  [ТС]
Не подскажете, почему информация, относящаяся к массивам, так странно отображается во всплывающих подсказках отладчика, хотя всё остальное, включая даже символы кириллицы, отображается превосходно?
Миниатюры
Особенности работы с файлами в PureBasic  
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
13.02.2023, 15:22  [ТС]
Впрочем, как оказалось, не только массивы. Сейчас заметил, что во всплывающих подсказках отладчика все служебные слова тоже отображаются точно с таким же набором каракулей.
Это мне не особо мешает, но просто хочется понять причину. Если проблема в кодировке, тогда почему такая избирательность?
0
12 / 12 / 0
Регистрация: 02.07.2014
Сообщений: 106
13.02.2023, 15:49
Покажите реальный код.
Я не первый раз вижу сообщения на эту тему, но у себя не могу воспроизвести.

Добавлено через 8 минут
p.s. Понял. Речь именно о всплывающих. И да проблема есть.
Вероятно в 6.1 по правят.
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
13.02.2023, 16:12  [ТС]
Цитата Сообщение от useful Посмотреть сообщение
p.s. Понял. Речь именно о всплывающих. И да проблема есть.
Вероятно в 6.1 по правят.
Спасибо за информацию. На самом деле, это не мешает.
Если у всех так, тогда я спокоен, могу дальше не пытаться отыскать причину. Думал, что с кодировками какие-то проблемы.
0
Эксперт по электронике
6494 / 3124 / 331
Регистрация: 28.10.2011
Сообщений: 12,289
Записей в блоге: 7
13.02.2023, 20:22
Цитата Сообщение от Power_Basic Посмотреть сообщение
почему информация, относящаяся к массивам, так странно отображается во всплывающих подсказках отладчика
Видимо неправильная кодировка при передаче данных отладчиком.
Текст должны быть таким:
Переменная не найдена 'MyArray'.
Во всплывающей подсказке отображаются только переменные и структуры. Остальное нужно смотреть через Отладчик -> Просмотр переменных.

Цитата Сообщение от useful Посмотреть сообщение
Вероятно в 6.1 по правят.
Если разработчики вообще знают об этой проблеме.
1
12 / 12 / 0
Регистрация: 02.07.2014
Сообщений: 106
14.02.2023, 05:00
https://www.purebasic.fr/engli... 0c3ac672b5
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.02.2023, 05:00
Помогаю со студенческими работами здесь

Особенности работы с COM-портом
...доброго времени суток, уважаемые форумчане! Имеется программа-драйвер COM-порта (архив COM-порт.rar и общий вид приложены). Свои функции...

Особенности работы fread
Решаю типовую задачу: считывание заголовка bmp-файла (точечного рисунка). Однако у меня ничего не получалось. В ходе расследования...

Особенности работы с обобщениями
Здравствуйте! Разбираюсь с обобщениями. Набросала такой код: public class Test { public static void Main() { // your code...

особенности работы c css
Доброго времени суток. Вопрос такой: Почему контейнер с кнопкой уезжает? <div></div> <div> ...

особенности работы @namelookup
как известно Syntax @NameLookup( ; username; itemtoreturn ) .... username Text or text list. Specify primary or alternate...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru