Что я сделал не так?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Что я сделал не так?

Сообщение Andrey A Kireev » 22.03.2004 (Пн) 16:24

Код: Выделить всё
Private Sub Command1_Click()
    Dim Buff() As Byte
    Dim FileSize As Long
'откроем файл
    Open "c:\00000489.JPG" For Binary As #1
'узнаем его размер
    FileSize = LOF(1)
'сделаем массив размером с файл
    ReDim Buff(FileSize)
'считаем файл в массив
    Get #1, , Buff()
'задаем новый файл
    NewFile = FreeFile
    Open "c:\rezult.jpg" For Output As #NewFile
'записываем в новый файл наш массив
    Write #NewFile, Buff()
'закроем все файлы
    Close #NewFile
    Close #1
End Sub


Код вроде примитивный. Считываем файл в массив, и из масива пишем в файл.
Но в результате получаем файл в два раза меньшего размера, и покореженым содержимым.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4160
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 22.03.2004 (Пн) 16:49

Второй файл нужно открывать тоже "for binary", и делать "put" вместо "write".

Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Сообщение Andrey A Kireev » 22.03.2004 (Пн) 17:05

На счет PUT все понятно.
А почему нельзя Write-ть или надо предварительно масив перелопачивать, но странно то что я ведь его и так с самого начала сделал бинарным а не стринговым, должен был нормально и такой вариант скушаться.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4160
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 22.03.2004 (Пн) 17:26

Вот как раз если бы буфер был строкой (не массивом), тогда метод ТЕКСТОВОГО вывода Write работал бы правильно (почти, добавлял бы лишние символы, типа 0A 0D в конце строк).

Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Сообщение Andrey A Kireev » 22.03.2004 (Пн) 17:45

Тоесть метод Write подходит только для стринговых переменных и массивов?
Вот этого коментария я в своем хелпе не видел. :(

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4160
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 22.03.2004 (Пн) 18:07

Write понимает binary как строку, где на символ приходится 2 байта. Причем не все комбинации байт допустимы, вместо них печатается "?". Кроме того напечатанное берется в кавычки. а если печатать несколько раз - разделяется запятыми либо переводом строки.
Тебе как раз можно использовать при желании и строку, но выводить все равно через PUT.

Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Сообщение Andrey A Kireev » 22.03.2004 (Пн) 18:23

Вот именно куча "?" у меня в результате и получалась. :(
Благодарю за разьяснения.

Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Сообщение Andrey A Kireev » 23.03.2004 (Вт) 11:36

Вчера как и было подсказано заменил Write на Put.
И сразуже заметил несколько багов присущих даже такому элементарному способу.
Код: Выделить всё
Private Sub Command1_Click()
    Dim Buff() As Byte
    Dim FileSize As Long
'откроем файл
    Open "c:\00000489.JPG" For Binary As #1
'узнаем его размер
    FileSize = LOF(1)
'сделаем массив размером с файл
    ReDim Buff(FileSize)
'считаем файл в массив
    Get #1, , Buff()
'задаем новый файл
    NewFile = FreeFile
    Open "c:\rezult.jpg" For Binary As #NewFile
'записываем в новый файл наш массив
    Put #NewFile,  , Buff()
'закроем все файлы
    Close #NewFile
    Close #1
End Sub

В этом варианте заметилось следующее:
В результате получается файл на 1 байт больше положеного. Как оказалось массив элементов начинается не с 1 а с 0 в результате чего при переопределении массива размеров с исконный файл мы получим FileSize + 0й байт в начале массива.
Это можно исправить переназначая массив как ReDim Buff(1 To FIleSize) тоесть исключая нулевую ячейку самого массива.
Но и это оказалось не без бага. Ибо если откроется файл 0-го размера (пустой) получится ReDim Buff(1 To 0) ну и ошибка соответственно. Да и переназначить массив 0-м размером тоже не получится ибо он просто обязан содержать хотябы один элемент и никак иначе, пусть даже это 00h.
Одним словом насколь я смог понять придется либо после FileSize = LOF(1) ставить условия и ветвить либо формирование массива либо его обход без создания массива.

Если есть какой более простой способ более коректного обхождения таких ситуаций, подскажите.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.03.2004 (Вт) 13:17

используй не байтовый массив, а стринговый буфер.
Lasciate ogni speranza, voi ch'entrate.

Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Сообщение Andrey A Kireev » 23.03.2004 (Вт) 13:35

А не скушаются ли в стринговом массиве символы не относящиеся к текстовым.
Не будет ли у меня результат как с Write где в результате получались вопросы вместо кода.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.03.2004 (Вт) 13:41

Все будет пучком, только стринговый буфер надо загружать/выгружать используя Get/Put (а не Input/Write). Кстати, можно файл открывать и как Output, только данные надо выгружать не Write #1, buff$, а Print #1, buff$; (точка с запятой обязательно).
Lasciate ogni speranza, voi ch'entrate.

Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Сообщение Andrey A Kireev » 23.03.2004 (Вт) 14:09

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

Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Сообщение Andrey A Kireev » 24.03.2004 (Ср) 10:06

Вчера опробовал загрузку и выгрузку через стринговый массив.
Тоесть ранее бинарный массив Dim Buff() As Byte задекларировал как стринговый Dim Buff() As String.
В результате чего впринципе комманды Get и Put возрожать не стали, но прога начала работать с массивом раз в 1.000-и дольше вместо долей секунды обработка занимала 2-3 минуты на 500кб файла.
А также в результате получался файл в три раза большего размера 1я треть файла была в оригинале и без искажения, а оставшиеся 2/3 файла были забиты 00h.

Пришлось делать проверку размера файла и ветвление по способам обработки массива.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4160
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Сообщение Mikle » 24.03.2004 (Ср) 10:13

Чтобы работать со строкой - массив не нужен.

Dim S as string
S=space$(lof(1)) 'устанавливаем длину строки
get#1,,S
put#2,,S

Andrey A Kireev
Обычный пользователь
Обычный пользователь
 
Сообщения: 51
Зарегистрирован: 06.11.2003 (Чт) 10:05

Сообщение Andrey A Kireev » 24.03.2004 (Ср) 11:19

А вот такого способа я не видел, нужно опробовать.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot и гости: 16

    TopList