- 浏览: 1249696 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (193)
- ant/maven (6)
- algorithm (5)
- tomcat/weblogic/jboss (6)
- javascript/jquery (13)
- java (33)
- flex/flash (0)
- JPA/Hibernate/myBatis (18)
- java concurrent (7)
- test (2)
- windows/linux (6)
- java collection (7)
- design pattern (2)
- life/health (3)
- database (12)
- IDE (4)
- spring/ejb (20)
- html/css/ckeditor (7)
- jsp/servlet (3)
- java io (13)
- java security (4)
- jni (0)
- svn/git (2)
- english (2)
- java jmx (1)
- xml (1)
- struts/springmvc (9)
- middleware (2)
- cache (1)
- cglib (3)
最新评论
-
jlotusYo:
博主,真感谢。
Java 密码扩展无限制权限策略文件 -
senninha:
这个。。是api说明吧。。
ScheduledExecutorService 源码分析 -
zoutao2008:
请问大文件如何处理?按你这种方式的话,文件超过200M时就会报 ...
hessian系列之二:上传文件 -
lwj1113:
lwj1113 写道谢谢博主这么细致的demo;在系列五中通过 ...
myBatis系列之五:与Spring3集成 -
lwj1113:
谢谢博主这么细致的demo;在系列五中通过testng测试类跑 ...
myBatis系列之五:与Spring3集成
扩展java.io.FilterInputStream,代表的是可放回输入流。用于根据特定字符来判断流类型或编码等。
1. 内部存储:
2. 构造函数:
3. 读取
4. 放回
5. 预估剩余可读取字节数
6. 跳过
7. 不支持mark相关的操作
8. 例子:去除UTF文件的BOM头
BOM (Byte Order Mark),包含三个字节"EF BB BF"。文件的开始位置有这几个字节,表明是UTF文件,读取数据的时候需要忽略它们。
1. 内部存储:
protected byte[] buf; // 缓冲区,从底层流获取数据 protected int pos; // 下一个要读取字节的位置 protected volatile InputStream in; // 底层流,继承自FilterInputStream
2. 构造函数:
public PushbackInputStream(InputStream in, int size) { super(in); if (size <= 0) { throw new IllegalArgumentException("size <= 0"); } this.buf = new byte[size]; this.pos = size; } public PushbackInputStream(InputStream in) { this(in, 1); }
3. 读取
// 从缓冲区(+底层流)读取数据,放到指定数组上。返回读取字节的个数。 public int read(byte[] b, int off, int len) throws IOException { ensureOpen(); if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int avail = buf.length - pos; // 缓冲区可读取字节数 if (avail > 0) { if (len < avail) { // 缓冲区可读取字节数够用 avail = len; // 给avail赋值,防止len-avail相减为负 } System.arraycopy(buf, pos, b, off, avail); // 读取操作 pos += avail; // 读取位置后移 avail位 off += avail; // 偏移值后移 avail位 len -= avail; // 还需读取字节数 } if (len > 0) { // 还需读取 len = super.read(b, off, len); // 从底层流读取 if (len == -1) { // 未读取到数据 return avail == 0 ? -1 : avail; // avail为0,表示都没有读取到数据;否则为从缓冲区读取数 } return avail + len; // 总读取数 = 从缓冲区读取数 + 从底层流读取数 } return avail; // 从缓冲区读取数 }
4. 放回
public void unread(int b) throws IOException { ensureOpen(); if (pos == 0) { // 缓冲区已满 throw new IOException("Push back buffer is full"); } buf[--pos] = (byte) b; // 然后读取位置回退,该位置重新设置为原来的值 }
public void unread(byte[] b, int off, int len) throws IOException { ensureOpen(); if (len > pos) { // 缓冲区回退长度不够 throw new IOException("Push back buffer is full"); } pos -= len; // 回退len个字节 System.arraycopy(b, off, buf, pos, len); // 将len个字节放回 }
5. 预估剩余可读取字节数
public int available() throws IOException { ensureOpen(); return (buf.length - pos) + super.available(); // 缓冲区可读取数 + 底层可读取数 }
6. 跳过
public long skip(long n) throws IOException { ensureOpen(); if (n <= 0) { return 0; } long pskip = buf.length - pos; // 缓冲区可用存储位置个数 if (pskip > 0) { if (n < pskip) { // 可用个数比跳过个数少 pskip = n; // pskip赋值为n,防止n -= pskip小于0 } pos += pskip; // 读取位置后移pskip位 n -= pskip; // 还需跳过数 } if (n > 0) { // 还需跳过n个字节 pskip += super.skip(n); // 总跳过字节数 = 缓冲区跳过数 + 底层流skip方法跳过数 } return pskip; }
7. 不支持mark相关的操作
public boolean markSupported() { return false; } public synchronized void mark(int readlimit) { } public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); }
8. 例子:去除UTF文件的BOM头
BOM (Byte Order Mark),包含三个字节"EF BB BF"。文件的开始位置有这几个字节,表明是UTF文件,读取数据的时候需要忽略它们。
public class BOMCleaner { static final Logger LOG = LoggerFactory.getLogger(BOMCleaner.class); static final int BOM_1 = 0xEF; // BOM第一个字节 static final int BOM_2 = 0xBB; // BOM第二个字节 static final int BOM_3 = 0xBF; // BOM第三个字节 public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("D:/mine.txt"); InputStream cleanIs = getInputStreamWithoutBom(fis); } public static InputStream getInputStreamWithoutBom(InputStream in) throws IOException { PushbackInputStream pbIn = new PushbackInputStream(in, 3); byte[] bytes = new byte[3]; int count = pbIn.read(bytes); if (count == 3 && (bytes[0] & 0xFF) == BOM_1 && (bytes[1] & 0xFF) == BOM_2 && (bytes[2] & 0xFF) == BOM_3) { LOG.debug("变更文件存在BOM头"); } else { pbIn.unread(bytes); } return pbIn; } }
发表评论
-
Netty系列之一:回显服务端和客户端
2014-09-02 22:26 9442Netty是一款基于Java NIO的 ... -
ByteBuffer 源码分析
2014-04-14 11:32 01. duplicate() 创建一个新的ByteBuffe ... -
RandomAccessFile 源码分析
2012-11-08 22:12 0public RandomAccessFile(S ... -
Java IO 总结
2013-01-17 17:05 17261. Java的IO运用了装饰者模式,提供了一个称做链接(Ch ... -
FileWriter 源码分析
2012-08-04 12:07 0public class FileWriter exten ... -
StringReader 源码分析
2012-07-12 18:00 1344public class StringReader ext ... -
OutputStreamWriter 源码分析
2012-06-29 09:59 2590字符流通向字节流的桥梁:可使用指定的charset将要写入流中 ... -
InputStreamReader 源码分析
2012-06-28 14:54 2249InputStreamReader在字节流和字符流之间架起了桥 ... -
Writer 源码分析
2012-06-28 17:47 1236Writer是写入字符流的抽象类。子类必须实现的方法有 wri ... -
PrintWriter 源码分析
2012-06-21 09:55 0public class PrintWriter exte ... -
FilterOutputStream 源码分析
2012-05-31 09:54 0public class FilterOutputStr ... -
PipedInputStream 源码分析
2012-05-31 09:53 0public class PipedInputStrea ... -
InputStream的mark和reset方法测试
2012-05-31 09:43 7975public class InputStreamTest ... -
BufferedOutputStream 源码分析
2012-05-30 18:25 5250BufferedOutputStream实现了一个缓冲输出流。 ... -
Reader 源码分析
2012-05-30 15:53 1567读取字符流的抽象类。子类需要重写read(char[], ... -
InputStream 源码分析
2012-05-30 14:38 3647InputStream是所有输入字节流类的超类。所有Input ... -
FileChannel 源码解析
2012-05-29 15:41 0public abstract class FileCh ... -
FileInputStream 源码分析
2012-05-29 10:53 5199java.io.FileInputStream是从文件系统中获 ... -
File 类源代码解析
2013-10-12 17:01 58781. 分隔符 // 名称分隔符,Windows系 ...
相关推荐
在Java编程语言中,`PushbackInputStream`是一个用于处理输入流的类,它提供了一种回退(或称为退格)的功能。这个类是`java.io`包的一部分,主要用于在读取数据后允许将数据“推回”到流中,以便后续的读取操作可以...
- `PushbackInputStream`: 允许将已读取的字节“推回”到流中。 这些子类扩展了InputStream的功能,以满足不同场景的需求。 ### 应用场景 InputStream常用于读取各种数据源,如文件、网络连接、内存缓冲区等。通过...
**源码分析**: 在阅读Java IO源码时,可以看到这些Decorator类都遵循了相同的模式:定义一个与被装饰类相同接口的类,持有被装饰对象的实例,并在其方法中调用被装饰对象的方法,同时添加额外的功能。例如,...
java IO 字节流练习代码 FileInputStream和FileOutputStream BufferedInputStream 和 BufferedOutputStream DataInputStream 和 DataOutputStream ObjectInputStream和ObjectOutputStream ...PushbackInputStream
((PushbackInputStream) this.in).unread(buf, len - n, n); } else { byte[] b = new byte[1]; int ret = in.read(b); } } return charsRead; } } ``` 在这个类中,`MultiMemberGZIPInputStream` 扩展了 `...
- `PushbackInputStream` 和 `PushbackReader`:允许将数据推回输入流以便重读。 7. 文件观察和监听: - `FileAlterationObserver` 和 `FileAlterationListener`:监控文件系统的变化,例如文件创建、修改和删除...
PushbackInputStream inStream = new PushbackInputStream(socket.getInputStream()); String response = StreamTool.readLine(inStream); System.out.println(response); String[] items = response...
在Java编程中,UTF-8编码是一个非常常见且广泛使用的字符编码格式,它能支持全球大部分语言的字符表示。然而,UTF-8有一个特殊特性,那就是它可以带有Byte Order Mark(BOM),这是一个特殊的字节序列,用于标识数据...
- **PushbackInputStream**: 允许将数据推回到输入流中,以便重新读取。 - **PushbackReader**: 字符流版本的`PushbackInputStream`。 这些FilterInputStream及其相应的输出流(如`DataOutputStream`、`...
PushbackInputStream允许“回退”或退回已读取的字节,这在需要重新处理某些数据时非常有用。PipedStream允许两个线程间通过管道进行数据传输。 7. 文件复制示例 下面是一个使用Java I/O流进行文件复制的例子: ```...
PushbackInputStream PushbackInputStream 为另一个输入流添加性能,即“推回 (push back)”或“取消读取 (unread)”一个字节的能力。 PushbackReader 允许将字符推回到流的字符流 reader。 RandomAccessFile 此类...
#### 六、案例分析 ##### 6.1 输入字节流案例 **案例1:读取文件内容** ```java FileInputStream in = new FileInputStream("test.txt"); byte[] b = new byte[1024]; int len; while ((len = in.read(b)) != -1)...
实际的示例代码可能会包含这些概念的实际应用,也可能涵盖其他高级特性,如管道流(PipedInputStream和PipedOutputStream),或者装饰模式下的过滤流(如CheckedInputStream和PushbackInputStream)。要深入了解,你需要...
PushbackInputStream允许将已读取的数据重新送回输入流。此外,ObjectInputStream可以反序列化由ObjectOutputStream序列化的对象,SequenceInputStream则可以将多个InputStream连接起来,按顺序读取。 Reader和...
* PushbackInputStream OutputStream的类型: * ByteArrayOutputStream * FileOutputStream * PipedOutputStream * FilterOutputStream * ByteArrayOutputStream * DataOutputStream * BufferedOutputStream * ...
- `PushbackInputStream`允许在读取过程中将部分数据重新推回流中,主要用于高级解析场景。 #### 四、案例分析:增强FileOutputStream功能 假设我们需要实现一种功能,即首先将要写入文件的数据缓存在内存中,...
- **`PushbackInputStream`**:允许数据重新推回到流中。 #### 四、字符流详解 字符流主要用于文本数据的处理,更加高效且易于操作。 ##### 1. 基础字符流 - **`CharArrayReader`**:从一个字符数组创建输入流。...
- `PushbackInputStream` 允许读取的数据被“推回”到流中,以便再次读取。 6. Propertity类: - `Properties` 类用于处理属性列表(键值对),常见于配置文件的读写。 在实际编程中,我们通常会结合使用这些流...
除了基本的输入输出流,还有一些特殊类型的流,如LineNumberInputStream提供行号功能,PushbackInputStream允许回退已读取的字节,而SequenceInputStream允许合并多个输入流。PrintStream是实用工具类,它可以格式化...
这就是FilterStream和PushbackInputStream等过滤流的作用,它们可以串联多个流,实现数据预处理、错误检测等功能。例如,DataInputStream和DataOutputStream可以对基本数据类型进行高效的读写。 管道流...