j2me 讀取多編碼格式外部文本文件
吶 想起來有些流不支持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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

posted on 2010-06-01 20:34 colonleado 閱讀(1695) 評論(0) 編輯 收藏 所屬分類: J2me