Это довольно сложная задача. Если вы можете убедиться, что заголовки HTTP Content-Length
и Content-Type
присутствуют в запросе на загрузку (или в составном теле, когда это запрос multipart/form-data
), тогда он было бы легко с помощью RandomAccessFile
. Длина содержимого является обязательной, чтобы RandomAccessFile
знал, как долго будет длиться файл, и запишите символ в нужной позиции. Кодировка символов (которая обычно присутствует в качестве атрибута заголовка типа контента) обязательна, чтобы знать, сколько байтов будет учитывать символ (поскольку RandomAccessFile
основано на байтах и, например, кодировка UTF-8 является переменной-байтовой длина).
Вот пример запуска (оставляя в стороне очевидную обработку исключений):
package com.stackoverflow.q2725897;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
public class Test {
public static void main(String... args) throws Exception {
// Stub input. You need to gather it yourself from your sources.
File file = new File("/file.txt");
long length = file.length(); // Get it from HTTP request header using file upload API in question (Commons FileUpload?).
String encoding = "UTF-8"; // Get it from HTTP request header using file upload API in question (Commons FileUpload?).
InputStream content = new FileInputStream(file); // Get it from HTTP request body using file upload API in question (Commons FileUpload?).
// Now the real job.
Reader input = new InputStreamReader(content, encoding);
RandomAccessFile output = new RandomAccessFile(new File("/filereversed.txt"), "rwd");
CharsetEncoder encoder = Charset.forName(encoding).newEncoder();
for (int data; (data = input.read()) != -1;) {
ByteBuffer bytes = encoder.encode(CharBuffer.wrap(new char[] { (char) data }));
length -= bytes.limit();
output.seek(length);
output.write(bytes.array());
}
// Should actually be done in finally.
input.close();
output.close();
}
}
Если эти заголовки отсутствуют (особенно важно Content-length
), вам действительно нужно сначала сохранить его на диске до конца потока, а затем перечитать и перевернуть его таким же образом с помощью RandomAccessFile
.
Обновление : на самом деле это будет сложнее, чем кажется. Всегда ли гарантируется одинаковая кодировка символов ввода? Если так, что это будет? Кроме того, что бы вы хотели сделать, например, суррогатные символы и символы новой строки? Приведенный выше пример не учитывает это правильно. Но это, по крайней мере, дает основную идею.