呐 想起来有些流不支持Mark(),所以对代码做了一些修改 如果不支持Mark()那么就自定义一个Mark()其实就是重新new一个流
具体什么流不支持Mark()我也说不全,那就这样,网络流?
因为微软的文本txt默认可以保存的编码格式有
UTF-8
Unicode big endian
Unicode
还有ANSI四种
那么就先实现这四个吧
使用起来很方便
调用该类的静态方法readFile,参数给出文件的相对路径和想要的缓冲区空间模式(FILE_SIZE_SMALL, FILE_SIZE_NORMAL,
FILE_SIZE_BIG, FILE_SIZE_MAX)就可以以字符串的形式得到那个文本文件里面的内容了
下面上源代码
1package streams;
2
3import java.io.IOException;
4import java.io.InputStream;
5
6
7/** *//**
8 *
9 * 读取外部文本文件<br>
10 * 自动识别编码格式 包括 <b>UTF-8/</b> <b>Unicode big endian/</b> <b>Unicode/</b>
11 * <b>ANSI</b><br>
12 *
13 * 读取完毕返回一个字符串
14 *
15 * @author Colonleado
16 *
17 */
18public class CInputFileStream {
19
20 /** *//**
21 * FILE_SIZE_SMALL 支持256个汉字<br>
22 * FILE_SIZE_NORMAL 支持512个汉字<br>
23 * FILE_SIZE_BIG 支持1024个汉字<br>
24 * FILE_SIZE_MAX 支持2048个汉字<br>
25 */
26 public static final byte FILE_SIZE_SMALL = 0, FILE_SIZE_NORMAL = 1,
27 FILE_SIZE_BIG = 2, FILE_SIZE_MAX = 3;
28
29 /** *//**
30 * 索引编码头
31 */
32 private static final int CODE_Unicode = 0xFFFE,
33 CODE_Unicode_big_endian = 0xFEFF, CODE_UTF_8 = 0xEFBBBF;
34
35 /** *//**
36 * 读取一个外部文件 <br>
37 * 可以是Unicode或Unicode_big_endian或UTF_8任何一种编码格式 自动识别 <br>
38 * 注意ANSI并不能储存中文 <br>
39 * 所以如果你的文本文件保存为ANSI并且内含中文那么读取出来将会是乱码<br>
40 * 也就是说ANSI格式的文本只能包含数字和字母且不要有中文的标点<br>
41 *
42 * @param path
43 * @param fileSizeMode
44 * @return
45 * @throws Exception
46 */
47 public static String readFile(String path, byte fileSizeMode)
48 throws Exception {
49
50 byte buf[] = null;
51
52 int size = 0;
53
54 switch (fileSizeMode) {
55
56 case FILE_SIZE_SMALL:
57
58 buf = new byte[512];
59
60 break;
61
62 case FILE_SIZE_NORMAL:
63
64 buf = new byte[1024];
65
66 break;
67
68 case FILE_SIZE_BIG:
69
70 buf = new byte[2048];
71
72 break;
73
74 case FILE_SIZE_MAX:
75
76 buf = new byte[4096];
77
78 break;
79
80 }
81
82 InputStream is = new Object().getClass().getResourceAsStream(path);
83
84 if (is.markSupported()) {
85
86 is.mark(0);
87
88 } else {
89
90 System.out.println("不支持Mark的输入流,将使用自定义的reset方法");
91
92// throw new Exception("不支持Mark的输入流");
93
94 }
95
96 byte codeTypeBuf[] = new byte[2];
97
98 is.read(codeTypeBuf);
99
100 int codeType = ((codeTypeBuf[0] & 0xff) << 8) | (codeTypeBuf[1] & 0xff);
101
102 switch (codeType) {
103
104 case CODE_Unicode:
105
106 // Unicode
107 StringBuffer sb = new StringBuffer();
108
109 size = read(is, buf);
110
111 for (int j = 0; j < size;) {
112
113 int l = buf[j++];
114
115 int h = buf[j++];
116
117 char c = (char) ((l & 0xff) | ((h << 8) & 0xff00));
118
119 sb.append(c);
120
121 }
122
123 return sb.toString();
124
125 case CODE_Unicode_big_endian:
126
127 // Unicode big endian
128 sb = new StringBuffer();
129
130 size = read(is, buf);
131
132 for (int i = 0; i < size; i += 2) {
133
134 int cha = ((buf[i] & 0xff) << 8) | (buf[i + 1] & 0xff);
135
136 sb.append((char) cha);
137
138 }
139
140 return sb.toString();
141
142 }
143
144 reset(is, path);
145
146 codeTypeBuf = new byte[3];
147
148 is.read(codeTypeBuf);
149
150 codeType = ((codeTypeBuf[0] & 0xff) << 16)
151 | ((codeTypeBuf[1] & 0xff) << 8) | (codeTypeBuf[2] & 0xff);
152
153 if (codeType == CODE_UTF_8) {
154
155 // UTF-8
156 size = read(is, buf);
157
158 return new String(buf, 0, size, "UTF-8");
159
160 }
161
162 // other
163 reset(is, path);
164
165 size = read(is, buf);
166
167 return new String(buf, 0, size);
168
169 }
170
171
172 /** *//**
173 * 自己实现的重置输入流 如果可以mark就reset,否则重新创建一个输入流
174 * @param is
175 * @param path
176 * @return
177 */
178 private static InputStream reset(InputStream is, String path){
179
180 if(is.markSupported()){
181
182 try {
183
184 is.reset();
185
186 } catch (IOException e) {
187
188 e.printStackTrace();
189
190 }
191
192 }else{
193
194 try {
195
196 is.close();
197
198 } catch (IOException e) {
199
200 e.printStackTrace();
201
202 }
203
204 is = null;
205
206 is = new Object().getClass().getResourceAsStream(path);
207
208 }
209
210 return is;
211
212 }
213
214 /** *//**
215 * 读取输入流到缓冲区 完毕后关闭该流
216 * @param is
217 * @param buff
218 * @return
219 * @throws IOException
220 */
221 private static int read(InputStream is, byte buff[]) throws IOException {
222
223 int kl = 0;
224
225 kl = is.read(buff);
226
227 if (is != null) {
228
229 is.close();
230
231 }
232
233 return kl;
234
235 }
236
237}
238