Прочитать сегмент файла в Java / Android - PullRequest
4 голосов
/ 27 августа 2010

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

Я загружаю файлы на Android, используя HTTP-библиотеки Apache, в частности используюMultipartEntity.

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

Вот сценарий.

Файл FOO.BAR составляет 20 МБ.Я бы разбил его на несколько произвольных размеров, скажем, 1 МБ, что означает 20 блоков.Части № 3 и № 14 выходят из строя (возможно, сотовая связь / WiFi-соединение было плохим).Теперь я могу повторно загрузить только эти два блока, и все будет хорошо.

Что я хотел бы знать, так это как я могу читать только часть файла (например, данные между 3 МБ и 4 МБ)?

Часть файла должна быть объектом InputStream или File.

Спасибо, Макото

Ответы [ 3 ]

2 голосов
/ 27 августа 2010

Вы можете использовать метод skip (long) , чтобы пропустить количество байтов в InputStream, или вы можете создать RandomAccessFile для объекта File и вызвать его seek (long) метод установки указателя на эту позицию, чтобы вы могли начать чтение с него.

Приведенный ниже быстрый тест читает файл размером 4 МБ + (от 3 до 4 МБ) и записывает прочитанные данные в файл ".out".

import java.io.*;
import java.util.*;

public class Test {

    public static void main(String[] args) throws Throwable {
       long threeMb = 1024 * 1024 * 3;
       File assembled =  new File(args[0]); // your downloaded and assembled file
       RandomAccessFile raf = new RandomAccessFile(assembled, "r"); // read
       raf.seek(threeMb); // set the file pointer to 3mb
       int bytesRead = 0;
       int totalRead = 0;
       int bytesToRead = 1024 * 1024; // 1MB (between 3M and 4M

       File f = new File(args[0] + ".out");
       FileOutputStream out = new FileOutputStream(f);

       byte[] buffer = new byte[1024 * 128]; // 128k buffer 
       while(totalRead < bytesToRead) { // go on reading while total bytes read is
                                        // less than 1mb
         bytesRead = raf.read(buffer);
         totalRead += bytesRead;
         out.write(buffer, 0, bytesRead);
         System.out.println((totalRead / 1024));
       }
    }
}
1 голос
/ 27 августа 2010

Мне удалось выяснить это ... просто нужно было обнаружить, что существует ByteArrayInputStream, который позволил бы мне преобразовать мой буфер byte [] в InputStream.Теперь я могу отследить, какие куски вышли из строя, и обработать их.Спасибо Константину за вот мою реализацию:

    final int chunkSize = 512 * 1024; // 512 kB
    final long pieces = file.length() / chunkSize;
    int chunkId = 0;

    HttpPost request = new HttpPost(endpoint);

    BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file));

    for (chunkId = 0; chunkId < pieces; chunkId++) {
        byte[] buffer = new byte[chunkSize];

        stream.skip(chunkId * chunkSize);
        stream.read(buffer);

        MultipartEntity entity = new MultipartEntity();
        entity.addPart("chunk_id", new StringBody(String.valueOf(chunkId)));
        request.setEntity(entity);
        ByteArrayInputStream arrayStream = new ByteArrayInputStream(buffer);

        entity.addPart("file_data", new InputStreamBody(arrayStream, filename));

        HttpClient client = app.getHttpClient();
        client.execute(request);
    }
1 голос
/ 27 августа 2010

Используйте метод skip () потока FileInputStream для поиска нужного фрагмента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...