花了近两周的时间在看IO系统,感觉很复杂.有一个关于byteBuffer的例子想请教一下:
//: c12:GetChannel.java
// Getting channels from streams
// {Clean: data.txt}
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class GetChannel {
  private static final int BSIZE = 1024;
  public static void main(String[] args) throws Exception {
    // Write a file:
    FileChannel fc =
      new FileOutputStream("data.txt").getChannel();
    fc.write(ByteBuffer.wrap("Some text ".getBytes()));
    fc.close();    // Read the file:
    fc = new FileInputStream("data.txt").getChannel();
    ByteBuffer buff = ByteBuffer.allocate(BSIZE);
    fc.read(buff);
    buff.flip();
    while(buff.hasRemaining())
      System.out.print((char)buff.get());    
  }
} ///:~ 有这么几个问题要请教:
1)"some text"这个字符串在调用getBytes()后就变成了一个byte[]这样的数组,是不是这样?
2)对于每个字母,如's','o'等,它们都是char型的,应该是占用两个byte,所以说上边的byte[]数组应该是每两个数组元素才表示一个字母,如字母's'要占用byte[0]和byte[1]?
3)那么问题又有了,buff.get()是每次取一个byte的内容,再把这个byte转换为char,我的理解是第一次get(),取出的是字母's'的上半部分,第二次取出的是字母's'的下半部分.分别对他们转换成char.
是这么回事吗?

解决方案 »

  1.   

    1 是的
    2 不是,这个时候已经将S和o转化为byte型了,S就是byte[0],o就是byte[1],你直接System.out.println(b[0]),将得到S的ASCII码83
    3 同理
      

  2.   

    我这正好写了个截取字符串的程序如:输入“aa你好”截取4输出“aa你”若为3则是“aa”不输出半个汉字乱吗,我测试发现utf-8编码下一个汉字占用3个byte,我的程序只在GBK编码下。。希望对你有帮助
    ===========================
    /**
     * 截取规定字节数字符串(GBK编码下)
     */
    import java.util.Scanner;public class Test {
    public static void main(String[] args) {
    Scanner sc=new Scanner(System.in);
    System.out.println("请输入你要截取的字符串:");
    String line=sc.nextLine();
    int num=0;
    /**
     * 接收输入规定字节数,判断合法性
     */
    while(true){
    System.out.println("请输入你要截取的字节数:");
     String numStr=sc.nextLine();
     try{
     num=Integer.parseInt(numStr);//将字符串转化为int(try)
     if(num<0){//判断输入是否小于0
     System.out.println("输入数据为大于0的正整数");
     continue;
     }else{
     break;
     }
     }catch(Exception e){
     System.out.println("输入错误重新输入:");
     }
    }
    System.out.println("你要截取的字符串为:"+line);
    System.out.println("你要截取字节数:"+num);
    System.out.println("截取后字符串为:"+cutStr(line, num));//返回截取后字符串
    }

    /**
     *           截取字符串方法
     * @param str
     * @param num
     * @return  String:截取后字符串
     */
    public static String cutStr(String str,int num){
    int count=0;//标记在num前有几个英文字符
    byte[]strByte=str.getBytes();
    System.out.println(strByte.length);//获得输入字符串的byte数组
    byte[]newStrByte=new byte[num];//新的字符数组
    //判断语句,判断如何截取规定字节
    if(num<strByte.length){//在要截取长度小于要截取字符串长度时
    for(int i=0;i<newStrByte.length;i++){//给新数组赋值
    newStrByte[i]=strByte[i];
    if(strByte[i]>0){
    count++;
    }
    }
    if(newStrByte[num-1]<0){//要截取的地方是中文
    if((count%2==0&&num%2!=0)||(count%2!=0&&num%2==0)){//判断是中文前半部分还是后半部分(前半部分)
    String newStr=new String(newStrByte,0,num-1);
    return newStr;
    }else{
    return new String(newStrByte);//中文后半部分
    }
    }else{
    return new String(newStrByte);//查找地方不是中文
    }
    }else{
    return new String(strByte);//输入长度大于输入字符串长度
    }
    }
    }
      

  3.   

    我现在对byteBuffer的数据转换有这么个粗略的理解,也不知是否准确,写出来,大家探讨一下:在byteBuffer中存在的都是一个个的字节,所以如果我们要想把有用的数据存入byteBuffer,并以后可以显示出来,那麽必须调用相应的asLongBuffer().put()或asIntBuffer().put()这种方式,把byteBuffer转换成相应的视图buffer来存入相应的基本类型数据.
    把数据从byteBuffer有两种方法,一个还是调用asLongBuffer()等方法,把byteBuffer先转换成对应的视图Buffer,然后调用get()就可以以对应的数据类型来取出一个个的数据.如buffer.asLongBuffer.get(),这样可以取出一个Long, 还有一种方法,就是直接调用LongGet(),如buffer.LongGet(),这也可以取出一个Long数据.这就是我看了一天多总结出来的,不知道对不对,有没有什么补充的,谢谢
      

  4.   

    其实有些简单的方法直接看jdk源代码和api帮助文档更有效,一些类的算法实现大概都能弄清楚没有把握的一些方法做些小程序测试也能证实,而且更具说服力
      

  5.   

    我的感觉是你要输入什麽基本类型的数据到buffer中,就必须使用相应的buffer来接收,这些接收的Buffer就叫视窗Buffer.输出这些buffer的内容,你可以仍然使用对应的视窗,也可以调用bytebuffer对应的函数.