Почему мои двоичные данные становятся больше после получения их с веб-сервера? - PullRequest
0 голосов
/ 14 сентября 2018

Мне нужно обслуживать двоичный файл через веб-сервис, реализованный в Python / Django.Проблема в том, что когда я сравниваю исходный файл с переданным файлом с vbindiff , я вижу конечные байты в переданном файле, к сожалению, делая его бесполезным.

Доступ к двоичному файлу сохраняется с помощьюклиент на Java с:

HttpURLConnection userdataConnection = null;
    URL userdataUrl = null;
    try {
        userdataUrl = new URL("http://localhost:8000/app/vuforia/10");

        userdataConnection = (HttpURLConnection) userdataUrl.openConnection();
        userdataConnection.setRequestMethod("GET");
        userdataConnection.setRequestProperty("Content-Type", "application/octet-stream");
        userdataConnection.connect();

        InputStream userdataStream = new BufferedInputStream(userdataConnection.getInputStream());
        try (ByteArrayOutputStream fileStream = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[4094];
            while (userdataStream.read(buffer) != -1) {
                fileStream.write(buffer);
            }
            byte[] fileBytes = fileStream.toByteArray();
            try (FileOutputStream fos = new FileOutputStream("./test.dat")) {
                fos.write(fileBytes);
            }
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

Я думаю, что HttpURLConnection.getInputStream читает только тело ответа, или нет?

Этот код обслуживает данные в бэкэнде

в views.py:

if request.method == "GET":
    all_data = VuforiaDatabase.objects.all()
    data = all_data.get(id=version)
    return FileResponse(data.get_dat_bytes())

в models.py:

def get_dat_bytes(self):
    return self.dat_upload.open()

Как мне передать двоичные данные 1: 1?

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Вы всегда пишете кратные 4094 байта, независимо от того, сколько байтов вы фактически прочитали.

Не делай .write(buffer); напишите сумму , которую вы на самом деле прочитали. Это то, что userdataStream.read возвращает вам . Может возвращать число, меньшее размера буфера, , но все равно положительное.

Если ваш проект уже использует Apache Commons, вы можете просто использовать copyInputStreamToFile.

Примечание: 4K = 4096, а не 4094, и это смехотворно маленький буфер, если вы не используете что-то вроде смарт-карты. На ПК используйте как минимум несколько сотен килобайт.

0 голосов
/ 14 сентября 2018

Вы игнорируете возвращаемое значение InputStream.read.

Из документации :

Возвращает:

общее число байтов, считанных в буфер, или -1, если больше нет данных, поскольку достигнут конец потока.

Ваш код предполагает, что буферзаполненный каждым вызовом userdataStream.read(buffer), вместо проверки того, сколько байтов было фактически прочитано в buffer.

Вам вообще не нужно читать из InputStream.Просто используйте Files.copy :

Path file = Paths.get("./test.dat");

try (InputStream userdataStream = new BufferedInputStream(userdataConnection.getInputStream())) {
    Files.copy(userdataStream, file, StandardCopyOption.REPLACE_EXISTING);
}
...