吶 想起來有些流不支持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