Одна проблема, которую я вижу здесь, связана с адресом локальной переменной.
struct PartitionBounds bounds;
int status = pthread_create(&sorters[i], NULL, sort, &bounds);
bounds
является локальной переменной, и она исчезнет, и на каждой итерации будет создан новый экземпляр. Таким образом, ссылка на нее в sort
будет иметь неопределенное поведение .
Вы можете динамически распределять память.
struct PartionBounds *bounds = malloc(sizeof(*bounds));
int status = pthread_create(&sorters[i], NULL, sort, bounds);
Убедитесь, что вы free
запомнили память.
Решение состоит в том, чтобы свернуть свое собственное, создав Реализация InputStream
, которая, вероятно, будет использовать java.nio.charset.CharsetEncoder
для кодирования каждого char
или фрагмента char
в массив байтов для InputStream
по мере необходимости.
Ну, один из возможных способов:
PipedOutputStream
PipedInputStream
OutputStreamWriter
вокруг PipedOutputStream
(вы можете указать кодировку в конструкторе) OutputStreamWriter
, может быть прочитано из PipedInputStream
! Конечно, это выглядит довольно хакерским способом, но, по крайней мере, так.
На мой взгляд, самый простой способ сделать это - протолкнуть данные через Writer:
public class StringEmitter {
public static void main(String[] args) throws IOException {
class DataHandler extends OutputStream {
@Override
public void write(final int b) throws IOException {
write(new byte[] { (byte) b });
}
@Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
@Override
public void write(byte[] b, int off, int len)
throws IOException {
System.out.println("bytecount=" + len);
}
}
StringBuilder sample = new StringBuilder();
while (sample.length() < 100 * 1000) {
sample.append("sample");
}
Writer writer = new OutputStreamWriter(
new DataHandler(), "UTF-16");
writer.write(sample.toString());
writer.close();
}
}
Реализация JVM, которую я использую, проталкивала данные в виде фрагментов 8K, но вы могли бы иметь некоторые влияют на размер буфера, уменьшая количество символов, записываемых за один раз, и вызывая flush.
Альтернатива написанию вашей собственной оболочки CharsetEncoder для использования Writer для кодирования данных, хотя делать это правильно - боль , Это должна быть надежная (если неэффективная) реализация:
/** Inefficient string stream implementation */
public class StringInputStream extends InputStream {
/* # of characters to buffer - must be >=2 to handle surrogate pairs */
private static final int CHAR_CAP = 8;
private final Queue<Byte> buffer = new LinkedList<Byte>();
private final Writer encoder;
private final String data;
private int index;
public StringInputStream(String sequence, Charset charset) {
data = sequence;
encoder = new OutputStreamWriter(
new OutputStreamBuffer(), charset);
}
private int buffer() throws IOException {
if (index >= data.length()) {
return -1;
}
int rlen = index + CHAR_CAP;
if (rlen > data.length()) {
rlen = data.length();
}
for (; index < rlen; index++) {
char ch = data.charAt(index);
encoder.append(ch);
// ensure data enters buffer
encoder.flush();
}
if (index >= data.length()) {
encoder.close();
}
return buffer.size();
}
@Override
public int read() throws IOException {
if (buffer.size() == 0) {
int r = buffer();
if (r == -1) {
return -1;
}
}
return 0xFF & buffer.remove();
}
private class OutputStreamBuffer extends OutputStream {
@Override
public void write(int i) throws IOException {
byte b = (byte) i;
buffer.add(b);
}
}
}