呐 想起来有些流不支持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)就可以以字符串的形式得到那个文本文件里面的内容了
下面上源代码
1
package streams;
2
3
import java.io.IOException;
4
import 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
*/
18
public 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