需求
当时有个需求是,前端要展示一个XML文件(具体是bpm2流程文件)的内容。一般来说,后端返回文件的下载URL,前端下载读取即可,但啥原因忘记了,还是由后端返回文件内容给前端。即读取XML文件,将其标签在内的所有内容转换为String来返回。
读取本地文件的demo
/**
* 代码片段
* 读取本地文件的demo
*/
try {
// 读取 xml 文件
File fileinput = new File("C:\\Users\\c-xiongb01\\Documents\\WXWork\\1688851135150110\\Cache\\File\\2021-12\\diagram.XML");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fileinput);
// 方法1:将xml文件转化为String
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(doc), new StreamResult(sw));
System.out.println(sw.toString());
System.out.println("end");
//方法二,和方法一类似,但格式与文件原本的样式不是一模一样
//DOMSource domSource = new DOMSource(doc);
//StringWriter writer = new StringWriter();
//StreamResult result = new StreamResult(writer);
//TransformerFactory tf = TransformerFactory.newInstance();
//Transformer transformer = tf.newTransformer();
//transformer.transform(domSource, result);
//System.out.println(writer.toString());
} catch (Exception e) {
log.error("getReviseBpmnFile 读取文件异常,url:" + reviseBpmnFile);
throw new BusinessException("读取文件异常!");
}
读取远程文件的demo
/**
* 代码片段
* 读取远程文件的demo
*/
String reviseBpmnFile = "远程文件地址,比如oss的文件url";
String fileString = "";
try {
//读取远程文件URl
InputStream in = LoadFile.downLoadFile(reviseBpmnFile);
//读取 xml 文件
File fileinput = LoadFile.copyInputStreamToFile(in);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fileinput);
//将xml文件转化为String
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(doc), new StreamResult(sw));
fileString = sw.toString();
} catch (Exception e) {
log.error("getReviseBpmnFile 读取文件异常,url:" + reviseBpmnFile);
throw new BusinessException("读取文件异常!");
}
//LoadFile工具类
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
public class LoadFile {
public static InputStream downLoadFile(String url) {
try {
URL file1 = new URL(url);
HttpURLConnection httpConnection = (HttpURLConnection) file1.openConnection();
InputStream input = httpConnection.getInputStream();
return input;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将InputStream流转化为File文件对象
*
* @param inputStream
* @return
* @throws IOException
*/
public static File copyInputStreamToFile(InputStream inputStream) throws IOException {
File file = new File("README.md");//临时读取的文件,要保证路径存在
try (FileOutputStream outputStream = new FileOutputStream(file)) {
int read;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
}
return file;
}
}
思考
文件内容过大,Java 的String类型能够接收吗
程序员都知道,Java中的类型变量的容量是有限的,超过容量就会报异常。此接口完成之后,就当心文件内容过大,超过String的容量,因此就去查阅相关资料。
JDK8及其以前String使用char数组,JDK9及其以后使用Byte数组。
从编译角度,数组有效长度是【0-65565】但是第二个加粗的地方又解释了,因为虚拟机还需要1个字节的指令作为结束,所以其实真正的有效范围是【0-65564】。
从运行角度,类Integer我们可以看到Integer的最大范围是2^31, 由于数组是从0开始的,所以数组的最长的尝长度可以使【0~2^31 】通过计算是大概4GB。
这里读取的使BPM2流程土,一般流程图内容超过4GB的还是很少的。