Ну, да, вы можете изменить это, но это имеет смысл. Base64 используется для создания двоичных данных - сгенерированных или управляемых приложением - совместимых с текстовой внешней средой. Таким образом, закодированные в base 64 данные всегда требуются снаружи, а декодированные двоичные данные - внутри.
Приложение обычно не выполняет никаких операций над базой 64 * 1007. * закодированные сами данные; просто необходимо передавать двоичные данные с другим приложением , когда требуется или ожидается текстовый интерфейс .
Если вы хотите экспортировать двоичные данные во внешнюю среду, естественно, вы бы использовать выходной поток. Если эти данные необходимо кодировать в базе 64, убедитесь, что вы отправляете данные в выходной поток, который кодирует в базу 64.
Если вы хотите импортировать двоичные данные извне, вы должны использовать входной поток. Если эти данные закодированы в базе 64, вам сначала нужно их декодировать, поэтому убедитесь, что вы декодируете их, а затем обрабатываете их как двоичный поток.
Позволяет создать небольшой фрагмент изображения. Допустим, у вас есть приложение, которое работает в текстовой среде, но работает с двоичными данными. Важной частью является направление стрелок из контекста приложения слева.
Затем вы получите для ввода (чтение вызовов):
{APPLICATION} <- (binary data decoding) <- (base64 decoding) <- (file input stream) <- [BASE 64 ENCODED FILE]
для этого вы, естественно, используете входные потоки.
Итак, давайте посмотрим на вывод (запись вызовов):
{APPLICATION} -> (binary data encoding) -> (base64 encoding) -> (file output stream) -> [BASE 64 ENCODED FILE]
, для этого вы, естественно, используете выходные потоки.
Эти потоки могут быть подключены к каждому другие с помощью связывают их вместе , то есть используют один поток в качестве родителя другого потока.
Вот пример в Java. Обратите внимание, что создание двоичного кодера / декодера в самом классе данных немного уродливо; как правило, вы бы использовали для этого другой класс - я надеюсь, что этого достаточно для демонстрационных целей.
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Base64;
public class BinaryHandlingApplication {
/**
* A data class that encodes to binary output, e.g. to interact with an application in another language.
*
* Binary format: [32 bit int element string size][UTF-8 element string][32 bit element count]
* The integers are signed, big endian values.
* The UTF-8 string should not contain a BOM.
* Note that this class doesn't know anything about files or base 64 encoding.
*/
public static class DataClass {
private String element;
private int elementCount;
public DataClass(String element) {
this.element = element;
this.elementCount = 1;
}
public String getElement() {
return element;
}
public void setElementCount(int count) {
this.elementCount = count;
}
public int getElementCount() {
return elementCount;
}
public String toString() {
return String.format("%s count is %d", element, elementCount);
}
public void save(OutputStream out) throws IOException {
DataOutputStream dataOutputStream = new DataOutputStream(out);
// so here we have a chain of:
// a dataoutputstream on a base 64 encoding stream on a fileoutputstream
byte[] utf8EncodedString = element.getBytes(UTF_8);
dataOutputStream.writeInt(utf8EncodedString.length);
dataOutputStream.write(utf8EncodedString);
dataOutputStream.writeInt(elementCount);
}
public void load(InputStream in) throws IOException {
DataInputStream dataInputStream = new DataInputStream(in);
// so here we have a chain of:
// a datainputstream on a base 64 decoding stream on a fileinputstream
int utf8EncodedStringSize = dataInputStream.readInt();
byte[] utf8EncodedString = new byte[utf8EncodedStringSize];
dataInputStream.readFully(utf8EncodedString);
this.element = new String(utf8EncodedString, UTF_8);
this.elementCount = dataInputStream.readInt();
}
}
/**
* Create the a base 64 output stream to a file; the file is the text oriented
* environment.
*/
private static OutputStream createBase64OutputStreamToFile(String filename) throws FileNotFoundException {
FileOutputStream textOutputStream = new FileOutputStream(filename);
return Base64.getUrlEncoder().wrap(textOutputStream);
}
/**
* Create the a base 64 input stream from a file; the file is the text oriented
* environment.
*/
private static InputStream createBase64InputStreamFromFile(String filename) throws FileNotFoundException {
FileInputStream textInputStream = new FileInputStream(filename);
return Base64.getUrlDecoder().wrap(textInputStream);
}
public static void main(String[] args) throws IOException {
// this text file acts as the text oriented environment for which we need to encode
String filename = "apples.txt";
// create the initial class
DataClass instance = new DataClass("them apples");
System.out.println(instance);
// perform some operation on the data
int newElementCount = instance.getElementCount() + 2;
instance.setElementCount(newElementCount);
// write it away
try (OutputStream out = createBase64OutputStreamToFile(filename)) {
instance.save(out);
}
// read it into another instance, who cares
DataClass changedInstance = new DataClass("Uh yeah, forgot no-parameter constructor");
try (InputStream in = createBase64InputStreamFromFile(filename)) {
changedInstance.load(in);
}
System.out.println(changedInstance);
}
}
Особо обратите внимание на цепочку потоков и, конечно, отсутствие каких-либо буферов вообще . Я использовал URL-безопасную базу 64 (если вы хотите использовать вместо нее HTTP GET).
В вашем случае, конечно, вы можете сгенерировать запрос HTTP POST, используя URL и напрямую кодируйте в извлеченный поток OutputStream
, обернув его. Таким образом, нет необходимости кодировать (широко) буферизованные данные в формате base64. Смотрите примеры того, как добраться до OutputStream
здесь .
Помните, что если вам нужно выполнить буферизацию, вы делаете это неправильно.
Как уже упоминалось в комментариях, HTTP POST не требует кодирования base 64, но теперь вы знаете, как можно кодировать base 64 напрямую в соединение HTTP.
java.util.Base64
speci c примечание: хотя base 64 - это текст, поток base64 генерирует / потребляет байты; это просто предполагает кодировку ASCII (это может быть забавно для текста UTF-16). Лично я думаю, что это ужасное дизайнерское решение; вместо этого они должны были обернуть Reader
и Writer
, даже если это немного замедляет кодирование.
В свою защиту различные стандарты base 64 и RF C также ошибаются.