方案二
// 按照行来读取 file
URL url = SourceFileUtil.class.getResource(file);
InputStream is =url.openStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
List<String> lineText = new ArrayList<>();
String str;
while ((str = rd.readLine()) != null) {
lineText.add(str);
}
return lineText;
// 按照行来读取 file
URL url = SourceFileUtil.class.getResource(file);
InputStream is =url.openStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
Java内容解读-文件资源
InputStream is =url.openStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
说明;
TestClassLoader.class.getResource("ehcache.xml")
TestClassLoader.class.getClassLoader().getResource("")
说明
Class.getResource和ClassLoader.getResource 最终调用的是 ClassLoader 类的 getResource 方法。
class.getResource(path) 只不过Class.getResource是先调用Class 的 getResource 方法,
在这个getResource 方法中,再去调用ClassLoader 类的getResource方法
相对路径
没有带“/”我们返回的是 TestClassLoader.class这个类所在的目录,
而带“/”返回的使我们项目的根目录的路径;
源码:
java.lang.Class
public final class Class<T> implements java.io.Serializable, GenericDeclaration,Type,AnnotatedElement
{ public java.net.URL getResource(String name) {
public URL getResource(String name) {
public ClassLoader getClassLoader() {
}
//硬编码
File file=new File("c:文件txt");
// 然后在使用file类创建一个文件文件输入流
FileInputStream in =new FileInputStream(file)
//如果路径包含Unicode字符,还需要将路径转码
String path = java.net.URLDecoder.decode(path, "UTF-8");
相对的获取方式: class.getResource() 和 class.getResourceAsStream()方式的使用在路径上是一致的
//class.getClassLoader().getResource() 和 class.getClassLoader().getResourceAsStream() 在使用时,路径选择上也是一样的
//方式1:(name不能以"/"左斜线开始,否则会认为是从根目录开始读取,抛出空指针异常)
InputStream fis = this.getClass().getClassLoader().getResourceAsStream("file/example.txt");
//方式2:(需要以"/"开始,读取的是相对于classthpasth的绝对路径)
InputStream fis = this.getClass().getResourceAsStream("/file/example.txt");
//但是以上两种方式在打包后可能都获取不到example.txt,解决方案如下:(路径不能以"/"开始)
InputStream fis = Thread.currentThread().getContextClassLoader().getResourceAsStream("file/example.txt");
在Web中说明
this.getClass().getClassLoader()的ClassLoader为AppClassLoader,
而 Thread.currentThread().getContextClassLoader()的ClassLoader为 AppClassLoader 为TomcatEbeddedWebAppClassLoader。
相关说法是:
将WEB程序发布到Tomcat里面运行。首先执行Tomcat org.apache.catalina.startup.Bootstrap类,
这时候的类加载器是 ClassLoader.getSystemClassLoader()。
而后面的WEB程序,里面的jar、resources都是由Tomcat内部来加载的,所以在代码中动态加载jar、资源文件的时候,
首先应该是使用Thread.currentThread().getContextClassLoader()。
如果使Test.class.getClassLoader(),可能会导致和当前线程所运行的类加载器不一致。
2. InputStream 基类
FileInputStream
FileInputStream 流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等
Java内容解读-文件资源
public abstract class InputStream implements Closeable {
java.io.InputStream
java.io.BufferedInputStream
java.io.ByteArrayInputStream
java.io.DataInputStream
java.io.FilterInputStream
InputStreamReader 类是从字节流到字符流的适配器 -属于适配器设计模式
设计模式
适配器模式,目的是将A对象通过适配、转换的方式转换成B对象来使用,
为什么转换为B对象?因为用户通过依赖B对象来使用。
IO中的 Reader InputStreamReader InputStream
设计模式
适配器 模式(Adapter Pattern)
装饰器 模式(Decorator Pattern)
桥接 模式(Bridge Pattern)
结构型模式的 适配器模式 和 桥接模式
01.适配器模式 是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
适配器模式主要有两种类型,
一种是类适配器模式 ,主要通过继承来实现适配器功能;
一种是对象适配器模式 ,通过组合来实现适配器功能。
02.桥接模式
桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。
它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
桥接模式的优点:
1、抽象和实现的分离,实现了解耦;
2、提升的扩展能力。
03.装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构
装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
应用
01.适配器模式与Reader、InputStream之间的适配 InputStreamReader
03.FilterInputStream 的子类有DataInputStream、BufferedInputStream,
是经典装饰器模式,对父类的各个方法进行了重写。
使用FileInputStream,read返回-1表示读到了末尾
BufferReader的作用是为其它Reader提供缓冲功能
遍历的标志
readLine() 方法是阻塞式的, 如果到达流末尾, 就返回null 读入的数据要注意有/r或/n或/r/n
List<String> lineText = new ArrayList<>();
String str;
while ((str = rd.readLine()) != null) {
lineText.add(str);
}
//注意 readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
// 每行都少首字符
while(br.read() != -1){
str = br.readLine();
}
/**
* @return The character read, as an integer in the range 0 to 65535 (<tt>0x00-0xffff</tt>),
* or -1 if the end of the stream has been reached
* @exception IOException If an I/O error occurs
*/
public int read() throws IOException
/**
* Reads a line of text. A line is considered to be terminated by any one
* of a line feed ('
'), a carriage return ('
'), or a carriage return
* followed immediately by a linefeed.
*
*
* @return A String containing the contents of the line, not including any line-termination characters,
* or null if the end of the stream has been reached
*
* @see java.io.LineNumberReader#readLine()
*
* @exception IOException If an I/O error occurs
*/
String readLine(boolean ignoreLF) throws IOException {
参考:
Java项目打包后获取classes路径下的资源文件 https://blog.csdn.net/dmxexcalibur/article/details/107542302