Как Вы объединяете два входных потока в Java?

Оба DictReader и DictWriter принимают произвольные аргументы, включая delimiter, и передают их нижележащему объекту reader или writer в качестве документации говорит:

class csv.DictReader (…)

Все остальные необязательные аргументы или аргументы ключевых слов передаются в базовый reader экземпляр.

blockquote>

class csv.DictWriter (…)

Любые другие необязательные или ключевые аргументы передаются в базовый [ 119] экземпляр.

blockquote>

Изменение соответствующей строки в вашем коде выше на

    r = csv.DictReader(infile, delimiter=";")

должно работать как положено.

27
задан Jonas 10 May 2012 в 13:02
поделиться

5 ответов

Как прокомментировано, не ясно, что вы подразумеваете под слиянием.

Взятие доступного ввода «случайно» из любого осложняется InputStream.available не обязательно дает вам полезный ответ и блокирует поведение потоков. Вам потребуется два потока для чтения из потоков и последующей передачи данных, скажем, через java.io.Piped (In | Out) putStream (хотя у этих классов есть проблемы). В качестве альтернативы для некоторых типов потоков может быть возможно использовать другой интерфейс, например java.nio неблокирующие каналы.

Если вы хотите, чтобы полное содержимое первого входного потока сопровождалось вторым : new java.io.SequenceInputStream (s1, s2) .

44
ответ дан 28 November 2019 в 04:40
поделиться

java.io.SequenceInputStream может быть тем, что вам нужно. Он принимает перечисление потоков и выводит содержимое первого потока, затем второго и т. Д., Пока все потоки не станут пустыми.

17
ответ дан 28 November 2019 в 04:40
поделиться

Вы можете написать собственную реализацию InputStream , которая сделает это. Пример:

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;

public class CatInputStream extends InputStream {
    private final Deque<InputStream> streams;

    public CatInputStream(InputStream... streams) {
        this.streams = new LinkedList<InputStream>();
        Collections.addAll(this.streams, streams);
    }

    private void nextStream() throws IOException {
        streams.removeFirst().close();
    }

    @Override
    public int read() throws IOException {
        int result = -1;
        while (!streams.isEmpty()
                && (result = streams.getFirst().read()) == -1) {
            nextStream();
        }
        return result;
    }

    @Override
    public int read(byte b[], int off, int len) throws IOException {
        int result = -1;
        while (!streams.isEmpty()
                && (result = streams.getFirst().read(b, off, len)) == -1) {
            nextStream();
        }
        return result;
    }

    @Override
    public long skip(long n) throws IOException {
        long skipped = 0L;
        while (skipped < n && !streams.isEmpty()) {
            int thisSkip = streams.getFirst().skip(n - skipped);
            if (thisSkip > 0)
                skipped += thisSkip;
            else
                nextStream();
        }
        return skipped;
    }

    @Override
    public int available() throws IOException {
        return streams.isEmpty() ? 0 : streams.getFirst().available();
    }

    @Override
    public void close() throws IOException {
        while (!streams.isEmpty())
            nextStream();
    }
}

Этот код не проверен, поэтому ваш пробег может отличаться.

4
ответ дан 28 November 2019 в 04:40
поделиться

Не то, чтобы я мог придумать. Вам, вероятно, придется прочитать содержимое двух потоков в byte [], а затем создать из него ByteArrayInputStream.

0
ответ дан 28 November 2019 в 04:40
поделиться

Вот Реализация MVar, специфичная для байтовых массивов (обязательно добавьте собственное определение пакета). Отсюда легко записать входной поток в объединенные потоки. Я могу опубликовать это тоже, если потребуется.

import java.nio.ByteBuffer;

public final class MVar {

  private static enum State {
    EMPTY, ONE, MANY
  }

  private final Object lock;

  private State state;

  private byte b;

  private ByteBuffer bytes;
  private int length;

  public MVar() {
    lock = new Object();
    state = State.EMPTY;
  }

  public final void put(byte b) {
    synchronized (lock) {
      while (state != State.EMPTY) {
        try {
          lock.wait();
        } catch (InterruptedException e) {}
      }
      this.b = b;
      state = State.ONE;
      lock.notifyAll();
    }
  }

  public final void put(byte[] bytes, int offset, int length) {
    if (length == 0) {
      return;
    }
    synchronized (lock) {
      while (state != State.EMPTY) {
        try {
          lock.wait();
        } catch (InterruptedException e) {}
      }
      this.bytes = ByteBuffer.allocateDirect(length);
      this.bytes.put(bytes, offset, length);
      this.bytes.position(0);
      this.length = length;
      state = State.MANY;
      lock.notifyAll();
    }
  }

  public final byte take() {
    synchronized (lock) {
      while (state == State.EMPTY) {
        try {
          lock.wait();
        } catch (InterruptedException e) {}
      }
      switch (state) {
      case ONE: {
        state = State.EMPTY;
        byte b = this.b;
        lock.notifyAll();
        return b;
      }
      case MANY: {
        byte b = bytes.get();
        state = --length <= 0 ? State.EMPTY : State.MANY;
        lock.notifyAll();
        return b;
      }
      default:
        throw new AssertionError();
      }
    }
  }

  public final int take(byte[] bytes, int offset, int length) {
    if (length == 0) {
      return 0;
    }
    synchronized (lock) {
      while (state == State.EMPTY) {
        try {
          lock.wait();
        } catch (InterruptedException e) {}
      }
      switch (state) {
      case ONE:
        bytes[offset] = b;
        state = State.EMPTY;
        lock.notifyAll();
        return 1;
      case MANY:
        if (this.length > length) {
          this.bytes.get(bytes, offset, length);
          this.length = this.length - length;
          synchronized (lock) {
            lock.notifyAll();
          }
          return length;
        }
        this.bytes.get(bytes, offset, this.length);
        this.bytes = null;
        state = State.EMPTY;
        length = this.length;
        lock.notifyAll();
        return length;
      default:
        throw new AssertionError();
      }
    }
  }
}
0
ответ дан 28 November 2019 в 04:40
поделиться
Другие вопросы по тегам:

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