RandomAccessFile是一个随机读写流。
今天在使用该流写入数据时,发现写入的数据读出来之后与源数据比较,结果是不相等。代码如下:
while((s=rw.readLine())!=null){ System.out.println("s:"+s); System.out.print("s:长度"+s.length()+"\n"); String[] record=s.split(","); System.out.print("record[0]:长度"+record[0].length()+"\n"); System.out.print("record[1]:长度"+record[1].length()+"\n"); System.out.print("record[2]:长度"+record[2].length()+"\n"); System.out.print("record[0]:按照长度打印"+record[0].length()+"\n"); for(int ii=0;ii<record[0].length();ii++){ System.out.print( record[0].charAt(ii)); } System.out.println(); System.out.println("record[0]:按照字符串"+record[0]); System.out.println(filename[filename.length-1]); System.out.println(record[0].compareTo(filename[filename.length-1])+" "+record[0]+" "+filename[filename.length-1]);
输出的结果如下:
我们发现读取的字符串s,内容为123456,0,1。但是长度却为21。
比较的两个字符串record[0]:123456,和filename[filename.length-1]:123456。比较的结果不为0。
哈?!黑人问号,怎么回事呢?
经过代码分析,发现,问题是出在了rw.writeChars(str);
因为writeChars写入文件时,字符数据被分了两个字节。高位为0,低位才是有效数据。
String str =filename[filename.length-1]+","+err[1]+","+count+"\n";
rw.writeChars(str);
下面我们针对writeChars这函数进行测试:写入函数有:bufferedWriter.write(s[0]);randomAccessFile.writeChars(s[0]);
public class tex { public static void main(String[] args){ String[] s="123,123456,123456789".split(","); System.out.println(s.length); System.out.println(s); System.out.println(s[0]+" "+s[0].length()); System.out.println(s[1]+" "+s[1].length()); System.out.println(s[2]+" "+s[2].length()); File file =new File("text.txt"); System.out.println(file.getAbsolutePath()); try { FileWriter fileWriter=new FileWriter(file); BufferedWriter bufferedWriter =new BufferedWriter(fileWriter); System.out.println(); System.out.println(s[0].length()); bufferedWriter.write(s[0]); bufferedWriter.newLine(); bufferedWriter.flush(); bufferedWriter.close(); fileWriter.close(); FileReader fileReader=new FileReader(file); BufferedReader bufferedReader =new BufferedReader(fileReader); String str= bufferedReader.readLine(); System.out.println(str.length()); bufferedReader.close(); fileReader.close(); }catch (Exception e){ } try { RandomAccessFile randomAccessFile =new RandomAccessFile( new File("ra.txt"),"rw"); randomAccessFile.writeChars(s[0]); System.out.println(s[0].length()); long p=0; randomAccessFile.seek(p); String str1=randomAccessFile.readLine(); System.out.println(str1); System.out.println(str1.length()); }catch (Exception e){ } } }
输出的结果如下:
我们可以发现,使用bufferedWriter.write(s[0])写入的数据,在读取之后的长度不变为3。
但是randomAccessFile.writeChars(s[0]);写入的数据,在读取之后的长度扩展为2倍为6;但输出显示依然是3个数据。
为了弄清楚为什么造成这两倍的差异,我们查看writeChars函数的实现
public final void writeChars(String s) throws IOException { int clen = s.length(); int blen = 2*clen; byte[] b = new byte[blen]; char[] c = new char[clen]; s.getChars(0, clen, c, 0); for (int i = 0, j = 0; i < clen; i++) { b[j++] = (byte)(c[i] >>> 8); b[j++] = (byte)(c[i] >>> 0); } writeBytes(b, 0, blen);
可以直观的看到,byte[] b的长度是char[] c的两倍。所以才会遇到之前的长度为6,输出却只有三个字符。
writeChar和writeChars原理一样,只是参数是一个int型(char等可以转化为int的可是可行的)。
另外我们从文件中也能看出两者的区别。writeChars,字符之间是有空格的。
集成环境中的终端输出,复制出来重新粘贴,会发现字符之间也有空格。
总结,我们尽量使用有编码方式的写入( writeUTF、readUTF ),或者自己设置好编码方式。编码方式这里不详细说