当我将它写入文件时,谁在 Base64 编码图像中添加“\n”? Java
Who is adding "\n" in Base64 encoded image when I write it in a file? Java
我在做什么
我需要通过 HTTPS 请求发送一个 JsonArray,其中包含 Base64 编码字符串中的一些数据和图像。如果数据存储在内存中,这很有效。
现在,我需要避免将所有数据加载到内存中,我正在 android 设备中创建一个临时文件,其中包含我需要发送的所有数据。
为了创建文件,我在他里面写了很多 JsonObjects。其中一些 JsonObjects 有一个表示图像的字段。当我检测到一个时,我会获取图像路径并使用 Base64 将其编码为字符串。
更新:
首先,我初始化文件并得到 bufferedWriter
File f = new File(privateSincronizePath+File.separator+"upload_"+timefile+".json");
f.createNewFile();
FileWriter fw = new FileWriter(f.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
下面是创建图片的代码:
JSONObject jobInf = new JSONObject();
jobInf.put("xx", "INSERT");
jobInf.put("xx", c.getString(c.getColumnIndex("xx")));
jobInf.put("xx", ""+c.getInt(c.getColumnIndex("xx")));
jobInf.put("xx", c.getString(c.getColumnIndex("xx")));
JSONObject jsonObject = new JSONObject(docu.filtre(dades, docu.getXx()));
Iterator<?> keys = jsonObject.keys();
boolean updated = false;
while(keys.hasNext() && !updated){
String key = (String)keys.next();
if (key != null && key.equals("path") && key.length() > 0){
jsonObject.put(key, getBase64EncodeFromImage(jsonObject.getString(key)));
updated = true;
}
}
jobInf.put("object", jsonObject);
escriure(bw, ","+jobInf.toString());
方法描述():
更新: 每次我完成 JsonObject 的创建时都会调用此方法。仅将 JsonObject 作为字符串附加到文件。
private void escriure(BufferedWriter bw, String s) throws IOException {
uploadLength += s.length();
bw.append(s);
}
最后,创建文件后,我正在读取它,并使用 OutputStream 将数据作为 Post 参数发送到服务器:
this.Https_url = new URL(url+"/sync.php?");
HttpsURLConnection con = (HttpsURLConnection) Https_url.openConnection();
con.setReadTimeout(60000);
con.setConnectTimeout(60000);
con.setRequestMethod("POST");
con.setDoInput(true);
con.setDoOutput(true);
con.setFixedLengthStreamingMode(uploadLength);
OutputStream os = con.getOutputStream();
InputStream inp = new FileInputStream(new File(privateSincronizePath+File.separator+"upload_"+timefile+".json"));
byte[] buffer = new byte[1024];
int len;
while ((len = inp.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
inp.close();
os.close();
// Establim la connexió:
con.connect();
问题是什么
问题很简单。当我在服务器中打开图像时,文件已损坏并且无法显示图像。
我注意到了什么
如果我抓取图片Base64字符串编码,写入文件,上传到服务器,图片就可以了!然后,写入文件后,图像似乎已损坏。
查了一下,发现写入文件后的Base64编码的字符串,每x个字符都有很多“\n”。
如果我删除所有这些“\n”或分界线,图像可以被服务器正确打开。
问题
是谁设置的断线?如何编写编码为 String "as is" 的 Base64?
预先感谢大家的帮助!
答案
正如 Schoenobates 的回答,解决方案是使用标志 NO_WRAP。
为了添加更多信息,我们在服务器端放置了这个函数来读取带有标志 URL_SAFE
的编码的 Base64 字符串
在coment of TOM in php.net上得到的函数是:
<?php
function base64url_decode($base64url)
{
$base64 = strtr($base64url, '-_', '+/');
$plainText = base64_decode($base64);
return ($plainText);
}
?>
感谢 Whosebug、Axel 和 Schoenobates 的宝贵时间!
那将是 Android Base64 class - 您需要设置标志以删除换行符:
byte[] image = ...;
Base64.encodeToString(image, Base64.NO_WRAP | Base64.URL_SAFE);
我在做什么
我需要通过 HTTPS 请求发送一个 JsonArray,其中包含 Base64 编码字符串中的一些数据和图像。如果数据存储在内存中,这很有效。
现在,我需要避免将所有数据加载到内存中,我正在 android 设备中创建一个临时文件,其中包含我需要发送的所有数据。 为了创建文件,我在他里面写了很多 JsonObjects。其中一些 JsonObjects 有一个表示图像的字段。当我检测到一个时,我会获取图像路径并使用 Base64 将其编码为字符串。
更新:
首先,我初始化文件并得到 bufferedWriter
File f = new File(privateSincronizePath+File.separator+"upload_"+timefile+".json");
f.createNewFile();
FileWriter fw = new FileWriter(f.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
下面是创建图片的代码:
JSONObject jobInf = new JSONObject();
jobInf.put("xx", "INSERT");
jobInf.put("xx", c.getString(c.getColumnIndex("xx")));
jobInf.put("xx", ""+c.getInt(c.getColumnIndex("xx")));
jobInf.put("xx", c.getString(c.getColumnIndex("xx")));
JSONObject jsonObject = new JSONObject(docu.filtre(dades, docu.getXx()));
Iterator<?> keys = jsonObject.keys();
boolean updated = false;
while(keys.hasNext() && !updated){
String key = (String)keys.next();
if (key != null && key.equals("path") && key.length() > 0){
jsonObject.put(key, getBase64EncodeFromImage(jsonObject.getString(key)));
updated = true;
}
}
jobInf.put("object", jsonObject);
escriure(bw, ","+jobInf.toString());
方法描述():
更新: 每次我完成 JsonObject 的创建时都会调用此方法。仅将 JsonObject 作为字符串附加到文件。
private void escriure(BufferedWriter bw, String s) throws IOException {
uploadLength += s.length();
bw.append(s);
}
最后,创建文件后,我正在读取它,并使用 OutputStream 将数据作为 Post 参数发送到服务器:
this.Https_url = new URL(url+"/sync.php?");
HttpsURLConnection con = (HttpsURLConnection) Https_url.openConnection();
con.setReadTimeout(60000);
con.setConnectTimeout(60000);
con.setRequestMethod("POST");
con.setDoInput(true);
con.setDoOutput(true);
con.setFixedLengthStreamingMode(uploadLength);
OutputStream os = con.getOutputStream();
InputStream inp = new FileInputStream(new File(privateSincronizePath+File.separator+"upload_"+timefile+".json"));
byte[] buffer = new byte[1024];
int len;
while ((len = inp.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
inp.close();
os.close();
// Establim la connexió:
con.connect();
问题是什么
问题很简单。当我在服务器中打开图像时,文件已损坏并且无法显示图像。
我注意到了什么
如果我抓取图片Base64字符串编码,写入文件,上传到服务器,图片就可以了!然后,写入文件后,图像似乎已损坏。
查了一下,发现写入文件后的Base64编码的字符串,每x个字符都有很多“\n”。 如果我删除所有这些“\n”或分界线,图像可以被服务器正确打开。
问题
是谁设置的断线?如何编写编码为 String "as is" 的 Base64? 预先感谢大家的帮助!
答案
正如 Schoenobates 的回答,解决方案是使用标志 NO_WRAP。 为了添加更多信息,我们在服务器端放置了这个函数来读取带有标志 URL_SAFE
的编码的 Base64 字符串在coment of TOM in php.net上得到的函数是:
<?php
function base64url_decode($base64url)
{
$base64 = strtr($base64url, '-_', '+/');
$plainText = base64_decode($base64);
return ($plainText);
}
?>
感谢 Whosebug、Axel 和 Schoenobates 的宝贵时间!
那将是 Android Base64 class - 您需要设置标志以删除换行符:
byte[] image = ...;
Base64.encodeToString(image, Base64.NO_WRAP | Base64.URL_SAFE);