Загрузка файла с Java (с индикатором выполнения)

Если я правильно понял ваш вопрос, вам нужно пройтись по дереву XML, так что вы, вероятно, захотите иметь рекурсивную функцию, которая делает это. Примерно так:

import pandas as pd
import xml.etree.ElementTree as ET

tree = ET.parse('file.xml')
root = tree.getroot()

def f(elem, result):
    result[elem.tag] = elem.text
    cs = elem.getchildren()
    for c in cs:
        result = f(c, result)
    return result

d = f(root, {})
df = pd.DataFrame(d, index=['values']).T
df

Out:

    values
Transmission    \n
TransmissionBody    \n
level1  \n
level2  \n
level3  \n
level4  \n
level5  \n
level6  \n
ColA    ABC
ColB    123

Обновление: Вот когда нам нужно сделать это для нескольких файлов XML. Я добавил еще один файл, похожий на исходный файл с ColA, строки ColB заменены на

<ColA>DEF</ColA>
<ColB>456</ColD>

Вот код:

def f(elem, result):
    result[elem.tag] = elem.text
    cs = elem.getchildren()
    for c in cs:
        result = f(c, result)
    return result

result = {}
for file in glob.glob('*.xml'):
    tree = ET.parse(file)
    root = tree.getroot()
    result = f(root, result)

df = pd.DataFrame(result, index=['values']).T
df

И вывод:

                    0    1
Transmission       \n   \n
TransmissionBody   \n   \n
level1             \n   \n
level2             \n   \n
level3             \n   \n
level4             \n   \n
level5             \n   \n
level6             \n   \n
ColA              ABC  DEF
ColB              123  456
30
задан soapergem 31 October 2008 в 19:49
поделиться

3 ответа

В итоге я наткнулся на апплет Java-загрузчика с открытым исходным кодом и нашел все, что мне нужно было знать, в его коде. Вот ссылки на сообщение в блоге, описывающее это, а также источник:

Статья
Исходный код

6
ответ дан 27 November 2019 в 23:21
поделиться

Apache common - очень хороший вариант. Apache common позволяет настраивать следующие вещи.

  1. Конфигурировать (файл xml) максимальный размер файла / размер загружаемого файла
  2. Путь к месту назначения (где сохранить загруженный файл)
  3. Установить временную шкалу. папка для замены файла, чтобы загрузка файла была быстрой.
1
ответ дан 27 November 2019 в 23:21
поделиться

Только мои 2 цента:

Это основано на ответе Тулера (на момент написания есть ошибка). Я немного изменил его, поэтому вот моя версия ответа Tuler и mmyers (кажется, я не могу редактировать их ответ). Я хотел попытаться сделать это немного чище и быстрее. Помимо ошибки (которую я обсуждаю в комментариях к их ответу), большая проблема, с которой я столкнулся с их версией, заключается в том, что она создает новый CountingOutputStream при каждой записи. Это может обойтись очень дорого с точки зрения памяти - тонны выделений и сборок мусора. Меньшая проблема заключается в том, что он использует делегат, когда он может просто расширить MultipartEntity . Не знаю, почему они выбрали это, поэтому я сделал это более привычным способом. Если кто-нибудь знает плюсы и минусы двух подходов, это было бы здорово. Наконец, метод FilterOutputStream # write (byte [], int, int) просто вызывает FilterOutputStream # write (byte) в цикле. Документация FOS рекомендует подклассы, переопределяющие это поведение и повышающие его эффективность. Лучший способ сделать это здесь - позволить базовому OutputStream обрабатывать запрос на запись.

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;

public class CountingMultiPartEntity extends MultipartEntity {

    private UploadProgressListener listener_;
    private CountingOutputStream outputStream_;
    private OutputStream lastOutputStream_;

    // the parameter is the same as the ProgressListener class in tuler's answer
    public CountingMultiPartEntity(UploadProgressListener listener) {
        super(HttpMultipartMode.BROWSER_COMPATIBLE);
        listener_ = listener;
    }

    @Override
    public void writeTo(OutputStream out) throws IOException {
        // If we have yet to create the CountingOutputStream, or the
        // OutputStream being passed in is different from the OutputStream used
        // to create the current CountingOutputStream
        if ((lastOutputStream_ == null) || (lastOutputStream_ != out)) {
            lastOutputStream_ = out;
            outputStream_ = new CountingOutputStream(out);
        }

        super.writeTo(outputStream_);
    }

    private class CountingOutputStream extends FilterOutputStream {

        private long transferred = 0;
            private OutputStream wrappedOutputStream_;

        public CountingOutputStream(final OutputStream out) {
            super(out);
                    wrappedOutputStream_ = out;
        }

        public void write(byte[] b, int off, int len) throws IOException {
                    wrappedOutputStream_.write(b,off,len);
                    ++transferred;
            listener_.transferred(transferred);
        }

        public void write(int b) throws IOException {
            super.write(b);
        }
    }
}
2
ответ дан 27 November 2019 в 23:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: