Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 | 2 |

 

  Вопрос: ПоБИТовая работа с файлами Добавлено: 11.06.06 08:53  

Автор вопроса:  ZagZag | ICQ: 295002202 
Надо записать в файл определенное кол-во бит указанного значения (от 1 до
255). Причем записывать надо не одну последовательность, а несколько.
Будет здорово если у кого-нибудь найдется процедура с параметрами типа:
позиция в файле (в битах), длина записи (в битах), значение бита

Уже всю голову изломал над проблемой

Для упрощения задачи уточню что именно я делаю:
Есть массив со значениями длин битовых цепочек (а как их еще назвать)
Этот массив нужно записать в файл и в дальнейшем его оттуда считать
Для этого потребуется чередовать значения битов (010101...) чтобы в
дальнейшем можно было получить значения обратно в массив

Пример:
Массив (тип Byte): {4,1,3,2,1}
В файле должно быть записано:
&b11110111.00100000
&hF7.20

Думаю если найдется процедура записи, то процедуру чтения я напишу сам, но
если и такая есть то буду вдвойне благодарен

PS
В сети не буду дня 3. Буду рад любым информативным ответам.

Ответить

  Ответы Всего ответов: 18  

Номер ответа: 1
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #1
Добавлено: 11.06.06 15:34
бит указанного значения (от 1 до 255)
Прикольные биты :)
Для чтения-записи используй CreateFile, SetFilePosition, WriteFile, ReadFile. По байтам они пишут именно так. Если нужно по битам (которые от 0 до 1), то сперва придется байты сформировать.

Ответить

Номер ответа: 2
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #2 Добавлено: 11.06.06 23:28
да судя с примера
Пример:
Массив (тип Byte): {4,1,3,2,1}
В файле должно быть записано:
&b11110111.00100000
&hF7.20

всё гораздо проще...
ему просто надо данные в бинарные данные перевести и записать в файл...

2 ZagZag
Алгоритмов полно, даже тут на форуме берёшь код символа, далее с ним вычисления которые записываются с права на лево... А вычисление все - всё делить не 2, и если есть остаток записывать 1, если нет 0...

6
6 / 2 = 3 (остатка нет) => 0
3 / 2 = 1,5 (остаток есть) => 1
1 / 2 = 0,5 (остаток есть) => 1

и того 6 в двоичном представлениии:
110

Осталось реализовать :)

Ответить

Номер ответа: 3
Автор ответа:
 ZagZag



ICQ: 295002202 

Вопросов: 87
Ответов: 1684
 Профиль | | #3 Добавлено: 12.06.06 02:28
2Sharp
Надо записать в файл определенное кол-во бит указанного значения (от
1 до
255)

Я наверное не правильно выразился :) Мне нужно записать/считать указанное
количество бит определенного значения в бинарный файл.
Я правильно тему назвал. Я же не новичек уже. В данном случае нужна именно
поБИТовая работа с файлами. Как побайтно работать я знаю.

Пример:

'Массив из длин битовых цепочек: {4,1,3,2,1}
Dim arData(4) As Byte
arData(0) = 4: arData(1) = 1: arData(2) = 3: arData(3) = 2: arData(4) = 1

Open "C:\data.dat" For Binary Access Write As #1
    For i = 0 To 4
        'А вот тут надо в файл записать биты:
        'Для четных элементов arData - нули, для нечетных - единички
        'Количество записываемых бит - значение arData(i)
        'Положение записи в файл - lngBitOffset
        lngBitOffset = lngBitOffset + arData(i)
    Next
Close #1


В результате в файле должно быть записано всего 2 байта(!):
0xF7 20
Чтобы было яснее в бинарном виде это будет:
11110111 - Элементы arData(0), arData(1), arData(2)
00100000 - Элементы arData(3), arData(4) и 5 пустых бит (ведь
полбайта не запишешь :)), значение которых всегда должно быть неравным
последней битовой цепочке

Сам себя процитирую :)
ведь полбайта не запишешь

Я это конечно же знаю, т.ч. предлагаю вычислять значение байта для записи
заранее, до того как он будет заполнен или пока не кончатся данные

Это реализовать нужно на PowerBasic. Я еще попытаюсь использовать его тип
BIT, но вроде он здесь не подойдет :(

PS
:) Я всетаки не удержался проверить почту... думаю проверю еще не раз
Спасибо за ответы
Попытаюсь использовать CreateFile, SetFilePosition, WriteFile, ReadFile
(хотя тестить я думаю лучше на Open, Seek, Put, Get) и бинарную математику

Ответить

Номер ответа: 4
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #4 Добавлено: 12.06.06 05:40
ну взять arData(0), посмотреть что в нём чётное значение, значит лепим единицы, затем посмотреть какое значение в arData(0) - знаем сколько единиц лепить... налепили последовательность, единиц/нулей, перевели её в десятичное представление, десятичное перевели в ascii и записали байт в файл. У тебя сам алгоритм неполучается, или что?

Ответить

Номер ответа: 5
Автор ответа:
 ZagZag



ICQ: 295002202 

Вопросов: 87
Ответов: 1684
 Профиль | | #5 Добавлено: 13.06.06 02:14
ну взять arData(0), посмотреть что в нём чётное значение, значит лепим единицы

Нет-нет, если индекс массива четный - лепим единицы, а не значение его элемента.

Да, вобщем-то интересует алгоритм.
А точнее - как в файл записать не кратное 8 кол-во бит
Еще уточню что данные будут браться не из массива, а из файла... размер которого может быть большой, т.ч. его в память целиком не загрузишь и результат чисто в памяти сформировать не получится, т.к. результат тоже не мало места займет.

На самом деле задачка интересная. Увы сегодня я над ней не думал... :) спал.

Ответить

Номер ответа: 6
Автор ответа:
 Morpheus



Вопросов: 224
Ответов: 3777
 Web-сайт: xury.zx6.ru
 Профиль | | #6
Добавлено: 13.06.06 03:07
А если первые несколько байт (ну, по традиции, четыре или можно пять так как биты) отдать под запись длины файла и указать сколько надо в файле считать бит, а потом такое количество бит и записать. конец последнего байта тупо заполнить нулями...

конечно на вопрос это не отвечает и вообще тривиальщина, но вдруг поможет

Ответить

Номер ответа: 7
Автор ответа:
 ZagZag



ICQ: 295002202 

Вопросов: 87
Ответов: 1684
 Профиль | | #7 Добавлено: 13.06.06 03:47
2Morpheus, ты предлагаешь записать количество всех значимых бит в файле?
Это моей задаче не поможет, т.к.:
1. Займет лишних 4-5 байта :)
2. Мне надо будет всеравно как-то различать при считывании границы начала-окончания каждой битовой цепочки (для вычисления ее длины), а. для этого их значения (0 и 1) должны чередоваться.

Записывать длины цепочек как байты, а не как битовые цепочки определенной длины мне тоже не подойдет, т.к. это сведет весь эффект сжатия на НЕТ (я пишу вещь на подобии архиватора)

Не хотел говорить, но в кратце опишу алгоритм сжатия (кста, может я велосипед изобретаю?)

1. Подсчитать в массив arChars() встречаемость каждого символа в исходном файле

            'Build symbols table
            ;DO UNTIL EOF(lngSrcFile)
                GET #lngSrcFile,,bytSymbol
                Symbols(bytSymbol) = Symbols(bytSymbol) + 1
                Indexes(bytSymbol) = bytSymbol
            LOOP

2. Сортировать полученные массивы по Indexes()
            'Sort symbols table
            ARRAY SORT Symbols(), TAGARRAY Indexes(), DESCEND


3. Записать в файл Indexes()
4. Перебирать побайтно #lngSrcFile и в #lngDestFile записывать биты
                GET #lngSrcFile,,bytSymbol
                ! XOR eax, eax
                ! MOV lngCount, eax
                ;DO UNTIL Indexes(lngCount) = bytSymbol
                    ! ADD lngCount, 1
                LOOP
                ! ADD lngCount, 1

                bitData = NOT bitData

                'Собственно запись бит
                '...
                '/Собственно запись бит

                lngWritedBitsCount = lngWritedBitsCount + lngCount


Значение битовой цепочки = bitData
Длина битовой цепочки = lngCount
Смещение = lngWritedBitsCount

Вот вроде и весь процесс архиваци

PS
Алгоритм (c) Сехан Алексей Петрович
Это не я :)

Ответить

Номер ответа: 8
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #8 Добавлено: 13.06.06 05:12
ну это теоретически невозможно. Ну подумай...
как в файл записать не кратное 8 кол-во бит
И что будет в размере этого файта?
1,5 (полтора) байт ? :)

выход, как уже сказили, сформировать из битов - байт. Но при этом всёравно как не крути 1 байт будет равен 8 битам. И никак и никогда нельзя записать на винт "пол байта"...
Даже если попробовать такое замутить на ассемблере, работая с винтом на самом низком уровне, и с процессором в самом нулевом кольце :) и вдруг получится записать "пол байта" и винт при это не подавится :) то всё это акруально будет до первого скандиска...

Алгоритмы архивации основаны совершенно на другом принципе, а именно на сдвиге битов... Но в файл пишутся всё те же байты, только на выходе их уже поменше :)

Ответить

Номер ответа: 9
Автор ответа:
 ZagZag



ICQ: 295002202 

Вопросов: 87
Ответов: 1684
 Профиль | | #9 Добавлено: 13.06.06 05:40
Понимаю что ПОЛБАЙТА звучит дико :)
В файл конечно должны писаться байты (и ничего меньше)
Но как эти байты динамически формировать из поставленной задачи?
В принципе можно сделать некий буффер (наверное так лучше назвать) в котором из данных бит будут формироваться байты. Байты должны формироваться до тех пор, пока количество составляющих их ЗНАЧАЩИХ (те которые собственно являются данными из битовых цепочек) бит станет кратным 8. в итоге и получится строка или массив, который и запишется на диск. После чего буффер обнулится и продолжится его заполнение новыми данными.

Внимание вопрос: Как сформировать этот буффер?
Прийдется делать что-то вроде двойного цикла?

'lngCount - Количество записываемых бит
'bitData - Значение записываемых бит
For lngIndex = 0 To lngCount
  For lngIndexByBits = 1 To 8
    'Последний_эл-т_буффера or IIF(bitData,1,0) * lngIndexByBits
    'Длина_бит = Длина_бит + 1
    '(Длина_бит mod 8) = 0 then
    '  Записать и обнулить буффер
  Next
Next

Что-то вроде того должно получиться :) Надо будет попробовать... А чем лучше буффер реализовать?

PS
Я как понял... ни кто этим не занимался? Или жадные все... Чтож буду первоПРОХОДИМЦЕМ

Ответить

Номер ответа: 10
Автор ответа:
 ZagZag



ICQ: 295002202 

Вопросов: 87
Ответов: 1684
 Профиль | | #10 Добавлено: 13.06.06 05:49
Не учел того что начинать запись прийдется с позиции бит, кратной 8. Можно конечно это доработать, но для моей задачи это не нужно

Еще забыл указать что после обнуления буффера, надо обнулять и переменную Длина_бит чтобы не было переполнения

И вообще мне этод метод с буффером неопределенной длинны не нравится - фиг знает сколько прийдется записывать цепочек со значением 254... Вроде 4 штуки, т.к. 254*4=1016 1016 mod 8 = 0 Итого, длина буффера 127 байт

Ответить

Номер ответа: 11
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #11 Добавлено: 13.06.06 21:01
да лучше в виде функции которая возвращает байт, а принимает массив arData. А внутри неё считается биты и собственно формируется байт...

Биты собирай хоть в строку...
строку из битов преобразовуй в десятичное чисто, это число Chr в байт и его возвращай...

Ответить

Номер ответа: 12
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #12
Добавлено: 13.06.06 22:27
Даже если попробовать такое замутить на ассемблере, работая с винтом на самом низком уровне, и с процессором в самом нулевом кольце :) и вдруг получится записать "пол байта" и винт при это не подавится :) то всё это акруально будет до первого скандиска...

Где ты такую забористую траву берешь? :)

Ответить

Номер ответа: 13
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #13 Добавлено: 14.06.06 04:13
иш какой, тебе скажи :) Та лана, чё для своих выпаду думаешь, вали в Харьков, я покажу... где и какую и у кого :)

Ответить

Номер ответа: 14
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #14 Добавлено: 14.06.06 12:07
Долго читал, несколько раз перечитывал, ничего не понял :(
У тебя одна из проблем в том, что не хочешь терять пространство на запись последних незначащих нулей? Если так, откажись от байта как единицы готовой (сформированой) информации и перейди к дворду или qword'у. Количество нерационально используемых бит уменьшится соответственно в 4 или 8 раз.

Ответить

Номер ответа: 15
Автор ответа:
 Victor



ICQ: 345743490 

Вопросов: 42
Ответов: 385
 Web-сайт: vt-dbnz.narod.ru
 Профиль | | #15
Добавлено: 14.06.06 13:35
Пусть записываем набор из n битов, начиная с бита № StartBitPos в файл. Для этого:

1. Читаем байты файла, покрываемые этим набором бит. От есть байты от StartBitPos\8 до (StartBitPos + n + 7)\8
2.конвертируем полыченнйе байты в биты Делаем массив битов. Его начало будет соответствовать биту № (StartBitPos\8)*8 файла.
3. Пишем в прочитанную последовательность битов наши n штук
4. Конвертируем биты обратно в байты и пишем байты в файл.

Вот код для конвертирования битов в байты и обратно:
Private Sub BitsToBytes(ByRef Arr() As Byte)
Dim i As Long, j As Long, h As Long
Dim bUB As Long, cUB As Long
Dim tB As Byte
bUB = UBound(Arr)
cUB = bUB \ 8
ReDim Preserve Arr(0 To (cUB + 1) * 8 - 1)
For i = 0 To cUB
    tB = 0
    h = i * 8
    For j = 0 To 7
        tB = tB + Arr(h + j) * Stepen2(j)
    Next j
    Arr(i) = tB
Next i
ReDim Preserve Arr(0 To cUB)
End Sub


Public Sub BytesToBits(ByRef Arr() As Byte)
Dim i As Long, j As Long, h As Long
Dim UB As Long, NUB As Long
UB = UBound(Arr)
NUB = (UB + 1) * 8 - 1
ReDim Preserve Arr(0 To NUB)
For i = NUB To 0 Step -1
    j = i \ 8
    h = i Mod 8
    Arr(i) = (Arr(j) Mod Stepen2(h + 1)) \ Stepen2(h)
Next i

End Sub

Я не уверен, что все это работает, так как писал примерно год назад и не помню даже, тестировал или нет.
Stepen2 - массив, в котором записаны степени двойки (от нуля до ??? наверно 9-ти)

Алгоритм наверняка не отличается производительностью, но все-таки..

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам