Передача данных из одного массива в другой

Рейтинг: 2Ответов: 2Опубликовано: 17.01.2015

Всем привет.

Столкнулся с такой проблемой:

Мне надо из массива данных (массив1) прочитать 245 байт и положить в другой массив (массив2), после чего повторить операцию, пока первый массив (массив1) не закончится, если в конце массива1 останется меньше 245 байт, то прочитать остаток и положить его в массив2.

Имеется вот такой код:

public static void myclass123(int keySize)
{        
        byte[] data = new byte[245];
        byte[] cipher = new byte[keySize];
        DataInputStream fis = new DataInputStream(new DataInputStream("/home/admin/workspace/myproject1/Test.txt"));
        DataOutputStream fos = new DataOutputStream(new FileOutputStream("/home/admin/workspace/myproject1/Data.enc"));
        int ret = 0, count = 0;
        while( (ret = fis.read(data)) > 0 ){
            fos.write (cipher = cf.doFinal(data, 0, ret));
            count += ret;
        }  
}

И все работает чудесно, пока fis у нас DataInputStream, но задача изменилась, и теперь вместо DataInputStream у меня byte[] MyArray1.
Теперь, когда я передаю массив в класс, например, вот так:

public static void myclass123(int keySize, byte[] fis)
{
        byte[] data = new byte[245];
        byte[] cipher = new byte[keySize];
        //DataInputStream fis = new DataInputStream(new DataInputStream("/home/admin/workspace/myproject1/Test.txt"));
        DataOutputStream fos = new DataOutputStream(new FileOutputStream("/home/admin/workspace/myproject1/Data.enc"));
        int ret = 0, count = 0;
        while( (ret = fis.read(data)) > 0 ){
            fos.write (cipher = cf.doFinal(data, 0, ret));
            count += ret;
        } 
}

ему не нравится fis.read(data), он говорит Cannot invoke read(byte[]) on the array type byte[], предлагает заменить на fis.lenght и убрать (data), после чего конструкция работает, только пишет в /home/admin/workspace/myproject1/Data.enc 0 байт, создает пустой файл - и тишина.

Сломал голову уже, честно признаю, что еще плохо понимаю, как работают массивы и java в принципе, но учусь, прошу помочь, уважаемые специалисты. Спасибо.

Ответы

▲ 4Принят

Массив в Java — примитивный тип данных (вероятно, даже правильнее было бы сказать «приближение к примитивному типу»?). Так или иначе, у него нет метода read. Еще важно то, что простой массив всегда имеет заявленную длину (память выделяется в момент инициализации переменной).

Прочитать блок данных можно так:

java.util.Arrays.copyOfRange(fis, 0, 0 + data.length); // data.length == 245

Здесь мы копируем из массива fis 245 элементов начиная с 0.

copyOfRange в качестве 3-го аргумента ожидает не длину, а позицию, на которой следует остановиться. То есть, чтобы прочитать вторую порцию из 245 байт, нужно вот что:

java.util.Arrays.copyOfRange(fis, 245, 245 + data.length); // data.length == 245

Что значит «копируем с 245 элемента по (245 + data.length = 245 + 245) = 490-й элемент»

Организовать цикл можно как-то так:

int blockSize = 245;
//byte[] data = new byte[blockSize];

int pos = 0;
int rangeMax;

while (pos < fis.length)
    {
    rangeMax = Math.min(pos + blockSize, fis.length);
    byte[] data = java.util.Arrays.copyOfRange(fis, pos, rangeMax);

    System.out.println(java.util.Arrays.toString(data));

    pos += data.length;
    }
▲ 3

Компилятор верно ругается, во втором варианте у вас переменная fis - это массив байтов, у него нет метода read (метод read есть у потока InputStream, который закомментирован). Я так понимаю, что вам нужно из массива fis читать по 245 байт в массив data и потом писать их в выходной поток? Если так, то принципиально код должен быть другой. И, не понятно, почему сразу не записать весь массив fis в выходной поток, зачем порцирование по 245 байт?