Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Java программирование > Общие вопросы по Java, Java SE, Kotlin
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.07.2016, 13:36   #1
BonBonita
 
Регистрация: 20.02.2015
Сообщений: 8
По умолчанию прочитать PNG-файл

Есть картинка, записанная в формате PNG.
Мне надо "выудить" из неё информацию...

Но сложности возникли уже при чтении первого символа:
вместо ожидаемого
89 50 4e 47 0d 0a 1a 0a
получаю
fffd 50 4e 47 d a 1a a
Код:
 public static void main(String[] args) 
    {
        String name;
        if (args.length == 0)
            name = "H:\\04.png";
        else
            name = args[0];
        File fileName = new File(name);
        char[] buffer = {};
        try(FileReader reader = new FileReader(fileName))
        {
            buffer = new char[(int)fileName.length()];
            reader.read(buffer);
        }
        catch(IOException ex)
        {
            System.out.println(ex.getMessage());
        }
        for(int i = 0; i < 8; i++)
            System.out.print(Integer.toHexString(buffer[i]) + " ");

    }
Что я делаю не так? Почему вместо 89 получаю fffd?
Возможно надо сменить кодировку консоли, тогда можете подсказать, как в IntelliGIDEA её поменять? Или это можно сделать программно?
BonBonita вне форума Ответить с цитированием
Старый 11.07.2016, 14:08   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,707
По умолчанию

Код:
byte[] cont = Files.readAllBytes(Paths.get(aFileName));
p51x вне форума Ответить с цитированием
Старый 11.07.2016, 14:35   #3
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

файл дай
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 11.07.2016, 16:13   #4
BonBonita
 
Регистрация: 20.02.2015
Сообщений: 8
По умолчанию

Да, любой png-файл пойдёт. Мне нужен этот:




Попробовала так:
Код:
 
        byte[] cont = Files.readAllBytes(Paths.get(name));
        for(int i = 0; i < 8; i++)
            System.out.print(cont[i] + " ");
В результате получила:
-119 80 78 71 13 10 26 10

Если верить http://wiki.metrotek.spb.ru/wiki/PNG...File_signature, то первые 8 байт png-файла должны быть такими:
Цитата:
* (decimal) 137 80 78 71 13 10 26 10
* (hexadecimal) 89 50 4e 47 0d 0a 1a 0a
* (ASCII C notation) \211 P N G \r \n \032 \n
Откуда взялась -119 ?

Последний раз редактировалось Alex11223; 11.07.2016 в 17:33.
BonBonita вне форума Ответить с цитированием
Старый 11.07.2016, 16:45   #5
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

byte не unsigned, и 137 больше 128.

А зачем кому-то верить когда можно самому посмотреть файл любым hex-редактором?
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 11.07.2016, 17:02   #6
BonBonita
 
Регистрация: 20.02.2015
Сообщений: 8
По умолчанию

Смотрела при помощи XVI32, там: 89 50 4e 47 0d 0a 1a 0a - т.е. всё сходится.
Чего-то главного я не понимаю...
BonBonita вне форума Ответить с цитированием
Старый 11.07.2016, 17:05   #7
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Сказал же, в Java byte не unsigned.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 11.07.2016, 17:22   #8
BonBonita
 
Регистрация: 20.02.2015
Сообщений: 8
По умолчанию

Т.е. читать файл в массив byte[] нельзя, т.к. мы выходим из диапазона допустимых значений... я правильно поняла?
Тогда игнорируем совет, который дал p51x, и возвращаемся к первому посту.
BonBonita вне форума Ответить с цитированием
Старый 11.07.2016, 17:31   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от BonBonita Посмотреть сообщение
Попробовала так:
Код:
 
        byte[] cont = Files.readAllBytes(Paths.get(name));
        for(int i = 0; i < 8; i++)
            System.out.print(cont[i] + " ");
попробуйте так:
Код:
 
        byte[] cont = Files.readAllBytes(Paths.get(name));
        for(int i = 0; i < 8; i++)
            System.out.print((cont[i] & 0xFF ) + " ");
p.s. Alex11223 прав!
см. Primitive Data Types
тип byte в Java принимает значения -128 до 127 (включительно).
поэтому его нужно преобразовать в int (код нашёл поиском по "java unsigned byte")
Serge_Bliznykov вне форума Ответить с цитированием
Старый 11.07.2016, 17:31   #10
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Можно, байты не меняются от того как на них смотрите.

Если надо конвертировать в unsigned, то например есть Byte.toUnsignedInt (Java8+)
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C++. Прочитать файл и вывести в другой файл каждую N-ую строку Straiker Помощь студентам 3 15.12.2009 05:49
Загрузить png файл MAcK Мультимедиа в Delphi 1 22.12.2008 22:23
Прочитать png формат в image Sin3v Общие вопросы Delphi 1 18.07.2008 11:45
как прочитать файл бодяга Общие вопросы Delphi 1 09.09.2007 20:37