Java 文件IO续

文件IO续

File类
    用来将文件和文件夹封装成对象 方便对文件和文件夹的属性信息进行操作
    File对象可以作为参数传递给流的构造函数

Demo1 File的构造方法

public class FileDemo {
  public static void main(String[] args) {

    constructorDemo();

  }

  public static void constructorDemo() {

    // 可以将一个已存在的,或者不存在的文件或者目录封装成file对象。
    File f1 = new File("c:\\a.txt");

    File f2 = new File("c:\\", "a.txt");

    File f = new File("c:\\");

    File f3 = new File(f, "a.txt");

    File f4 = new File("c:" + File.separator + "abc" + File.separator + "a.txt");
    System.out.println(f4);

  }
}

File类
    用于将文件和文件夹封装成对象。
    1,创建。
        boolean createNewFile():如果该文件不存在,会创建,如果已存在,则不创建。不会像输出流一样会覆盖。        
        boolean mkdir();
        boolean mkdirs();
    2,删除。
        boolean delete();
        void deleteOnExit();
        
    3,获取:
        String getAbsolutePath();
        String getPath();
        String getParent();
        String getName();
        long length();
        long lastModified();
        
    
    4,判断:
        boolean exists();
        boolean isFile();
        boolean isDirectory();

Demo2 File的常用方法

public class FileMethodDemo {
  public static void main(String[] args) throws IOException {

     getDemo();
     createAndDeleteDemo();
     isDemo();
     renameToDemo();

     listRootsDemo();
  }

  public static void listRootsDemo() {

    File file = new File("d:\\");

    System.out.println("getFreeSpace:" + file.getFreeSpace());
    System.out.println("getTotalSpace:" + file.getTotalSpace());
    System.out.println("getUsableSpace:" + file.getUsableSpace());

    // File[] files = File.listRoots();
    // for(File file : files){
    // System.out.println(file);
    // }
  }

  public static void renameToDemo() {

    File f1 = new File("c:\\9.mp3");

    File f2 = new File("d:\\aa.mp3");

    boolean b = f1.renameTo(f2);

    System.out.println("b=" + b);
  }

  public static void isDemo() throws IOException {
    File f = new File("aaa");

    // f.mkdir();
    f.createNewFile();

    // boolean b = f.exists();
    // System.out.println("b="+b);
    // 最好先判断是否存在。
    System.out.println(f.isFile());
    System.out.println(f.isDirectory());

  }

  public static void createAndDeleteDemo() throws IOException {

    File dir = new File("abc\\q\\e\\c\\z\\r\\w\\y\\f\\e\\g\\s");

    // boolean b = dir.mkdir();//make directory
    // System.out.println("b="+b);
    // dir.mkdirs();//创建多级目录
    System.out.println(dir.delete());

    // System.out.println(dir.delete());

    // 文件的创建和删除。
    // File file = new File("file.txt");

    /*
     * 和输出流不一样,如果文件不存在,则创建,如果文件存在,则不创建。
     */
    // boolean b = file.createNewFile();
    // System.out.println("b="+b);

    // boolean b = file.delete();
    // System.out.println("b="+b);

  }

  public static void getDemo() {
    // File file = new File("E:\\java0331\\day22e\\a.txt");
    File file = new File("a.txt");

    String name = file.getName();

    String absPath = file.getAbsolutePath();// 绝对路径。

    String path = file.getPath();

    long len = file.length();

    long time = file.lastModified();

    Date date = new Date(time);

    DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);

    String str_time = dateFormat.format(date);

    System.out.println("parent:" + file.getParent());

    System.out.println("name:" + name);
    System.out.println("absPath:" + absPath);
    System.out.println("path:" + path);
    System.out.println("len:" + len);
    System.out.println("time:" + time);
    System.out.println("str_time:" + str_time);

  }
}

Demo3 文件浏览器

public class FileTest {
  public static void main(String[] args) {

    File dir = new File("E:\\ADT");

    listAll(dir, 0);
  }

  public static void listAll(File dir, int level) {

    System.out.println(getSpace(level) + dir.getName());
    // 获取指定目录下当前的所有文件夹或者文件对象

    level++;
    File[] files = dir.listFiles();

    for (int x = 0; x < files.length; x++) {

      if (files[x].isDirectory()) {
        listAll(files[x], level);
      } else
        System.out.println(getSpace(level) + files[x].getName());
    }
  }

  private static String getSpace(int level) {

    StringBuilder sb = new StringBuilder();

    sb.append("|--");
    for (int x = 0; x < level; x++) {
      sb.insert(0, "|  ");
    }

    return sb.toString();
  }
}
}

Demo4 删除一个带文件的目录

public class RemoveDirTest {
  public static void main(String[] args) {
    
    File dir = new File("D:\\Java");
    // dir.delete();
    removeDir(dir);
  }

  public static void removeDir(File dir) {

    File[] files = dir.listFiles();

    for (File file : files) {

      if (file.isDirectory()) {
        removeDir(file);
      } else {
        System.out.println(file + ":" + file.delete());
      }
    }
    System.out.println(dir + ":" + dir.delete());
  }
}

 Properties集合:
    Map |--Hashtable |--Properties:
    1,该集合中的键和值都是字符串类型。 2,集合中的数据可以保存到流中,或者从流获取。
    3 通常该集合用于操作以键值对形式存在的配置文件。

Demo5 Properties的使用

public class PropertiesDemo {
  public static void main(String[] args) throws IOException {

    // methodDemo_4();
    // myLoad();

    test();
  }

  // 对已有的配置文件中的信息进行修改。
  /*
   * 读取这个文件。 并将这个文件中的键值数据存储到集合中。 在通过集合对数据进行修改。 在通过流将修改后的数据存储到文件中。
   */
  public static void test() throws IOException {
    // 读取这个文件。
    File file = new File("E:\\info.txt");
    if (!file.exists()) {
      file.createNewFile();
    }
    FileReader fr = new FileReader(file);

    // 创建集合存储配置信息。
    Properties prop = new Properties();

    // 将流中信息存储到集合中。
    prop.load(fr);

    prop.setProperty("wangwu", "16");

    FileWriter fw = new FileWriter(file);

    prop.store(fw, "");

    // prop.list(System.out);

    fw.close();
    fr.close();

  }

  // 模拟一下load方法。
  public static void myLoad() throws IOException {

    Properties prop = new Properties();

    BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));

    String line = null;

    while ((line = bufr.readLine()) != null) {

      if (line.startsWith("#"))
        continue;

      String[] arr = line.split("=");

      // System.out.println(arr[0]+"::"+arr[1]);
      prop.setProperty(arr[0], arr[1]);
    }

    prop.list(System.out);

    bufr.close();

  }

  public static void methodDemo_4() throws IOException {

    Properties prop = new Properties();

    // 集合中的数据来自于一个文件。
    // 注意;必须要保证该文件中的数据是键值对。
    // 需要使用到读取流。
    FileInputStream fis = new FileInputStream("info.txt");

    // 使用load方法。
    prop.load(fis);

    prop.list(System.out);

  }

  public static void methodDemo_3() throws IOException {
    Properties prop = new Properties();

    // 存储元素。
    prop.setProperty("zhangsan", "30");
    prop.setProperty("lisi", "31");
    prop.setProperty("wangwu", "36");
    prop.setProperty("zhaoliu", "20");

    // 想要将这些集合中的字符串键值信息持久化存储到文件中。
    // 需要关联输出流。
    FileOutputStream fos = new FileOutputStream("info.txt");

    // 将集合中数据存储到文件中,使用store方法。
    prop.store(fos, "info");

    fos.close();

  }

  /**
   * 演示Properties集合和流对象相结合的功能。
   */

  public static void methodDemo_2() {
    Properties prop = new Properties();

    // 存储元素。
    // prop.setProperty("zhangsan","30");
    // prop.setProperty("lisi","31");
    // prop.setProperty("wangwu","36");
    // prop.setProperty("zhaoliu","20");

    prop = System.getProperties();
    prop.list(System.out);
  }

  /*
   * Properties集合的存和取。
   */

  public static void propertiesDemo() {
    // 创建一个Properties集合。

    Properties prop = new Properties();

    // 存储元素。
    prop.setProperty("zhangsan", "30");
    prop.setProperty("lisi", "31");
    prop.setProperty("wangwu", "36");
    prop.setProperty("zhaoliu", "20");

    // 修改元素。
    prop.setProperty("wangwu", "26");

    // 取出所有元素。
    Set<String> names = prop.stringPropertyNames();

    for (String name : names) {
      String value = prop.getProperty(name);
      System.out.println(name + ":" + value);
    }
  }
}

Demo6 获取一个应用程序运行的次数,如果超过5次,给出使用次数已到请注册的提示。并不要在运行程序

public class PropertiesTest {
  public static void main(String[] args) throws IOException {

    getAppCount();

  }

  public static void getAppCount() throws IOException {

    // 将配置文件封装成File对象。
    File confile = new File("E:\\count.properties");

    if (!confile.exists()) {
      confile.createNewFile();
    }

    FileInputStream fis = new FileInputStream(confile);

    Properties prop = new Properties();

    prop.load(fis);

    // 从集合中通过键获取次数。
    String value = prop.getProperty("time");
    // 定义计数器。记录获取到的次数。
    int count = 0;
    if (value != null) {
      count = Integer.parseInt(value);
      if (count >= 5) {
        // System.out.println("使用次数已到,请注册,给钱!");
        // return;
        throw new RuntimeException("使用次数已到,请注册,给钱!");
      }
    }
    count++;

    // 将改变后的次数重新存储到集合中。
    prop.setProperty("time", count + "");

    FileOutputStream fos = new FileOutputStream(confile);

    prop.store(fos, "");

    fos.close();
    fis.close();

  }
}

IO包中的其他类
    打印流 PrintWriter PrintStream
        1,提供了打印方法可以对多种数据类型值进行打印。并保持数据的表示形式。
        2 它不抛IOException.
        构造函数,接收三种类型的值  1,字符串路径  2,File对象。3,字节输出流

Demo7 PrintStream

public class PrintStreamDemo {
  public static void main(String[] args) throws IOException {
    
    PrintStream out = new PrintStream("E:\\info.txt");
    
//    int by = read();
//    write(by);
    
//    out.write(610);//只写最低8位,
    
//    out.print(97);//将97先变成字符保持原样将数据打印到目的地。 
    
    out.close();
    
    
  }
}

Demo8 PrintWriter

public class PrintWriterDemo {
  public static void main(String[] args) throws IOException {
    /*
     * PrintWriter:字符打印流。 构造函数参数: 1,字符串路径。 2,File对象。 3,字节输出流。 4,字符输出流。
     */
    BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

    PrintWriter out = new PrintWriter(new FileWriter("out.txt"), true);

    String line = null;
    while ((line = bufr.readLine()) != null) {
      if ("over".equals(line))
        break;
      out.println(line.toUpperCase());
      // out.flush();
    }

    out.close();
    bufr.close();
  }
}

序列流 SequenceInputStream

Demo8 将1.txt 2.txt 3.txt文件中的数据合并到一个文件中。

public class SequenceInputStreamDemo {
public static void main(String[] args) throws IOException {
    ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
    for(int x=1; x<=3; x++){
      al.add(new FileInputStream("E:\\" + x+".txt"));
    }
    
    Enumeration<FileInputStream> en = Collections.enumeration(al);
    
    
    SequenceInputStream sis = new SequenceInputStream(en);
    
    FileOutputStream fos = new FileOutputStream("E:\\1234.txt");
    
    byte[] buf = new byte[1024];
    
    int len = 0;
    
    while((len=sis.read(buf))!=-1){
      fos.write(buf,0,len);
    }
    
    fos.close();
    sis.close();
    
  }
}

Demo9 文件切割

public class SplitFileDemo {
  private static final int SIZE = 1024 * 1024;

  public static void main(String[] args) throws Exception {

    File file = new File("E:\\cloud.apk");

    //splitFile(file);
    splitFile_2(file);
  }

  private static void splitFile_2(File file) throws IOException {

    // 用读取流关联源文件。
    FileInputStream fis = new FileInputStream(file);

    // 定义一个1M的缓冲区。
    byte[] buf = new byte[SIZE];

    // 创建目的。
    FileOutputStream fos = null;

    int len = 0;
    int count = 1;

    /*
     * 切割文件时,必须记录住被切割文件的名称,以及切割出来碎片文件的个数。 以方便于合并。
     * 这个信息为了进行描述,使用键值对的方式。用到了properties对象
     */
    Properties prop = new Properties();

    File dir = new File("E:\\partfiles");
    if (!dir.exists())
      dir.mkdirs();

    while ((len = fis.read(buf)) != -1) {

      fos = new FileOutputStream(new File(dir, (count++) + ".part"));
      fos.write(buf, 0, len);
      fos.close();
    }

    // 将被切割文件的信息保存到prop集合中。
    prop.setProperty("partcount", count + "");
    prop.setProperty("filename", file.getName());

    fos = new FileOutputStream(new File(dir, count + ".properties"));

    // 将prop集合中的数据存储到文件中。
    prop.store(fos, "save file info");

    fos.close();
    fis.close();

  }

  public static void splitFile(File file) throws IOException {

    // 用读取流关联源文件。
    FileInputStream fis = new FileInputStream(file);

    // 定义一个1M的缓冲区。
    byte[] buf = new byte[SIZE];

    // 创建目的。
    FileOutputStream fos = null;

    int len = 0;
    int count = 1;

    File dir = new File("E:\\partfiles");
    if (!dir.exists())
      dir.mkdirs();

    while ((len = fis.read(buf)) != -1) {

      fos = new FileOutputStream(new File(dir, (count++) + ".part"));
      fos.write(buf, 0, len);
    }

    fos.close();
    fis.close();

  }
}

Demo10 合并文件

public class MergeFile {
  public static void main(String[] args) throws IOException {

    File dir = new File("E:\\partfiles");

    mergeFile_2(dir);
  }

  public static void mergeFile_2(File dir) throws IOException {

    /*
     * 获取指定目录下的配置文件对象。
     */
    File[] files = dir.listFiles(new SuffixFilter(".properties"));

    if (files.length != 1)
      throw new RuntimeException(dir + ",该目录下没有properties扩展名的文件或者不唯一");
    // 记录配置文件对象。
    File confile = files[0];

    // 获取该文件中的信息================================================。

    Properties prop = new Properties();
    FileInputStream fis = new FileInputStream(confile);

    prop.load(fis);

    String filename = prop.getProperty("filename");
    int count = Integer.parseInt(prop.getProperty("partcount"));

    // 获取该目录下的所有碎片文件。 ==============================================
    File[] partFiles = dir.listFiles(new SuffixFilter(".part"));

    if (partFiles.length != (count - 1)) {
      throw new RuntimeException(" 碎片文件不符合要求,个数不对!应该" + count + "个");
    }

    // 将碎片文件和流对象关联 并存储到集合中。
    ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
    for (int x = 0; x < partFiles.length; x++) {

      al.add(new FileInputStream(partFiles[x]));
    }

    // 将多个流合并成一个序列流。
    Enumeration<FileInputStream> en = Collections.enumeration(al);
    SequenceInputStream sis = new SequenceInputStream(en);

    FileOutputStream fos = new FileOutputStream(new File(dir, filename));

    byte[] buf = new byte[1024];

    int len = 0;
    while ((len = sis.read(buf)) != -1) {
      fos.write(buf, 0, len);
    }

    fos.close();
    sis.close();

  }

  public static void mergeFile(File dir) throws IOException {

    ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();

    for (int x = 1; x <= 3; x++) {
      al.add(new FileInputStream(new File(dir, x + ".part")));
    }

    Enumeration<FileInputStream> en = Collections.enumeration(al);
    SequenceInputStream sis = new SequenceInputStream(en);

    FileOutputStream fos = new FileOutputStream(new File(dir, "1.bmp"));

    byte[] buf = new byte[1024];

    int len = 0;
    while ((len = sis.read(buf)) != -1) {
      fos.write(buf, 0, len);
    }

    fos.close();
    sis.close();

  }

}

class SuffixFilter implements FilenameFilter {

  private String suffix;
  
  public SuffixFilter(String suffix) {
    super();
    this.suffix = suffix;
  }

  @Override
  public boolean accept(File dir, String name) {

    return name.endsWith(suffix);
  }

}

ObjectInputStream 和 ObjectOutputStream

  对象的序列化和反序列化。
  writeObject  readObject
  Serializable标记接口
  关键字:transient //非静态数据不想被序列化可以使用这个关键字修饰。

Demo11

public class ObjectStreamDemo {
  public static void main(String[] args) throws IOException, ClassNotFoundException {

    writeObj();
    readObj();
  }

  public static void readObj() throws IOException, ClassNotFoundException {

    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\obj.object"));
    // 对象的反序列化。
    Person p = (Person) ois.readObject();

    System.out.println(p.getName() + ":" + p.getAge());

    ois.close();

  }

  public static void writeObj() throws IOException, IOException {

    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\obj.object"));
    // 对象序列化。 被序列化的对象必须实现Serializable接口。
    oos.writeObject(new Person("小强", 30));

    oos.close();

  }
}
public class Person implements Serializable/*标记接口*/ {

  /**
   * transient:非静态数据不想被序列化可以使用这个关键字修饰。 
   */
  private static final long serialVersionUID = 9527l;
  private transient String name;
  private static int age;
  
  
  public Person(String name, int age) {
    super();
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }
  
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
  
}

RandomAccessFile
    一看这个类名字,纠结。不是io体系中的子类。
    1,该对象即能读,又能写。
    2,该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素,
    3,可以通过getFilePointer方法获取指针的位置,和通过seek方法设置指针的位置
    4,其实该对象就是将字节输入流和输出流进行了封装。
    5,该对象的源或者目的只能是文件。通过构造函数就可以看出。

Demo12

public class RandomAccessFileDemo {
  public static void main(String[] args) throws IOException {

    // writeFile();
    // readFile();
    randomWrite();
  }

  public static void randomWrite() throws IOException {
    RandomAccessFile raf = new RandomAccessFile("E:\\ranacc.txt", "rw");

    // 往指定位置写入数据。
    raf.seek(3 * 8);

    raf.write("哈哈".getBytes());
    raf.writeInt(108);

    raf.close();
  }

  public static void readFile() throws IOException {

    RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "r");

    // 通过seek设置指针的位置。
    raf.seek(1 * 8);// 随机的读取。只要指定指针的位置即可。

    byte[] buf = new byte[4];
    raf.read(buf);

    String name = new String(buf);

    int age = raf.readInt();

    System.out.println("name=" + name);
    System.out.println("age=" + age);

    System.out.println("pos:" + raf.getFilePointer());

    raf.close();

  }

  // 使用RandomAccessFile对象写入一些人员信息,比如姓名和年龄。
  public static void writeFile() throws IOException {
    /*
     * 如果文件不存在,则创建,如果文件存在,不创建
     */
    RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "rw");

    raf.write("张三".getBytes());
    raf.writeInt(97);
    raf.write("小强".getBytes());
    raf.writeInt(99);
    //
    raf.close();
  }

}

管道流:需要和多线程技术相结合的流对象。
  PipedOutputStream  
  PipedInputStream

Demo13

public class PipedStream {
  public static void main(String[] args) throws IOException {

    PipedInputStream input = new PipedInputStream();
    PipedOutputStream output = new PipedOutputStream();

    input.connect(output);

    new Thread(new Input(input)).start();
    new Thread(new Output(output)).start();

  }

}

class Input implements Runnable {

  private PipedInputStream in;

  Input(PipedInputStream in) {
    this.in = in;
  }

  public void run() {

    try {
      byte[] buf = new byte[1024];
      int len = in.read(buf);

      String s = new String(buf, 0, len);

      System.out.println("s=" + s);
      in.close();
    } catch (Exception e) {
      // TODO: handle exception
    }

  }
}

class Output implements Runnable {
  private PipedOutputStream out;

  Output(PipedOutputStream out) {
    this.out = out;
  }

  public void run() {

    try {
      Thread.sleep(5000);
      out.write("hi,管道来了!".getBytes());
    } catch (Exception e) {
      // TODO: handle exception
    }
  }
}

IO包中其它类
    操作基本数据类型 DataInputStream DataOutputStream

Demo14

public class DataSteamDemo {
  public static void main(String[] args) throws IOException {

     writeData();
    readData();

  }

  public static void readData() throws IOException {

    DataInputStream dis = new DataInputStream(new FileInputStream("E:\\data.txt"));

    String str = dis.readUTF();

    System.out.println(str);
  }

  public static void writeData() throws IOException {

    DataOutputStream dos = new DataOutputStream(new FileOutputStream("E:\\data.txt"));

    dos.writeUTF("你好");

    dos.close();

  }
}

操作字节数组 ByteArrayInputStream ByteArrayOutputStream

Demo15

public class ByteArrayStreamDemo {
  public static void main(String[] args) {

    ByteArrayInputStream bis = new ByteArrayInputStream("abcedf".getBytes());
    
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
    int ch = 0;
    
    while((ch=bis.read())!=-1){
      bos.write(ch);
    }
    
    System.out.println(bos.toString());
  }
}

 

操作字符数组


操作字符串

编码表
    计算机只能识别二进制数据 早期由来是电信号
    为了方便应用计算机 让它可以识别各个国家的文字
    就将各个国家的文字用数字来表示 并一一对应 形成一张表
    就是编码表
常见编码表
    ASCII 美国标准信息交换码 用一个字节的7位表示
    ISO8858-1 拉丁码表 欧洲码表 用一个字节的8位表示
    GB2312 中国的中文编码表
    GBK 中国的中文编码表升级 加入更多中文字符
    Unicode 国际标准码 用两个字节表示一个字符
    UTF-8 最多用三个字节表示一个字符

  字符串 --> 字节数组:编码
  字节数组 --> 字符串:解码
  你好:GBK:  -60 -29 -70 -61
  你好: utf-8: -28 -67 -96 -27 -91 -67
  如果你编错了,解不出来
  如果编对了,解错了,有可能有救

三个编码例子

Demo1

public class EncodeDemo {
  public static void main(String[] args) throws IOException {

    String str = "谢谢";

    byte[] buf = str.getBytes("gbk");

    String s1 = new String(buf, "UTF-8");

    System.out.println("s1=" + s1);

    byte[] buf2 = s1.getBytes("UTF-8");// 获取源字节.

    printBytes(buf2);// -17 -65 -67 -17 -65 -67 -17 -65 -67
    // -17 -65 -67 -17 -65 -67 -17 -65 -67 -17 -65 -67
    // -48 -69 -48 -69
    String s2 = new String(buf2, "GBK");

    System.out.println("s2=" + s2);

    // encodeDemo(str);

  }

  public static void encodeDemo(String str) throws UnsupportedEncodingException {
    // 编码;
    byte[] buf = str.getBytes("UTF-8");

    // printBytes(buf);

    // 解码:
    String s1 = new String(buf, "UTF-8");

    System.out.println("s1=" + s1);
  }

  private static void printBytes(byte[] buf) {
    for (byte b : buf) {
      System.out.print(b + " ");
    }
  }
}

Demo2

public class LianTong {
public static void main(String[] args) throws IOException {
    
    String str = "联通";
    /*
    11000001
    10101010
    11001101
    10101000
    */

    
    byte[] buf = str.getBytes("gbk");
    
    for(byte b :buf){
      System.out.println(Integer.toBinaryString(b&255));
    }
  }
}

Demo3

public class Test {
  public static void main(String[] args) throws IOException {

    String str = "ab你好cd谢谢";
    // str = "ab琲琲cd琲琲";

    // int len = str.getBytes("gbk").length;
    // for(int x=0; x<len; x++){
    // System.out.println("截取"+(x+1)+"个字节结果是:"+cutStringByByte(str, x+1));
    // }

    int len = str.getBytes("utf-8").length;
    for (int x = 0; x < len; x++) {
      System.out.println("截取" + (x + 1) + "个字节结果是:" + cutStringByU8Byte(str, x + 1));
    }

    // String str = "琲";
    // byte[] buf = str.getBytes("gbk");
    // for(byte b : buf){
    // System.out.println(b);//-84 105
    // }

  }

  /*
   * 在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符。 但对应的字节数不同,一个汉字占两个字节。
   * 定义一个方法,按照最大的字节数来取子串。 如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个,
   * 那么半个就要舍弃。如果去四个字节就是“ab你”,取五个字节还是“ab你”.
   */

  public static String cutStringByU8Byte(String str, int len) throws IOException {

    byte[] buf = str.getBytes("utf-8");

    int count = 0;
    for (int x = len - 1; x >= 0; x--) {
      if (buf[x] < 0)
        count++;
      else
        break;
    }

    if (count % 3 == 0)
      return new String(buf, 0, len, "utf-8");
    else if (count % 3 == 1)
      return new String(buf, 0, len - 1, "utf-8");
    else
      return new String(buf, 0, len - 2, "utf-8");

  }

  public static String cutStringByByte(String str, int len) throws IOException {

    byte[] buf = str.getBytes("gbk");

    int count = 0;
    for (int x = len - 1; x >= 0; x--) {
      if (buf[x] < 0)
        count++;
      else
        break;
    }

    if (count % 2 == 0)
      return new String(buf, 0, len, "gbk");
    else
      return new String(buf, 0, len - 1, "gbk");
  }
}

 

posted @ 2015-11-30 19:51  幻奕  阅读(231)  评论(0编辑  收藏  举报