Stringbuffer使用注意
 
问题背景:
模拟客户端使用Socket请求服务器核心系统,核心系统正常响应,内容较大,近2715KB,大于2.6M多。
使用指定编码GBK来接收响应内容到过程中没有什么问题,正常接受,内容全部接受到,使用Stringbuffer.append。
问题是响应内容是这样格式的274429200019XXXX结尾内容,需要将前面一段数字内容清除,只留下中间那一段XXX的XML内容。这种情况理所当然substring。我是这样处理的,将响应结果res(String名字为res)转成toCharArray()。得到一个char Array,然后遍历这个char Array,使用Stringbuffer.append追加char。但是最后的处理结果老是丢失一段内容,弄得我怀疑Stringbuffer追加有数据容量限制,试了一下容量调整,最后无效果。考虑到接受响应结果也是用的StringBuffer,那里接受时没出问题,内容都没丢失,况且还是我要截取之前的内容,内容更大,这就不像是StringBuffer的问题,后来怎么整都不行,整了一天(不然我不会记录这个问题)。最后我用土办法,输出!一个一个char输出,遍历一次Char Array输出一次char。加了一个这样的处理,我发现最后几位char输出的竟然是经常看到的乱码内容"口口口口",晕倒了,我马上反应过来,肯定是乱码内容"口"影响到了StringBuffer.append,于是我用substring把乱码内容去掉,然后再次运行,OK!,数据没有丢失了。
 
总结:Stringbuffer.append追加的内容千万不要是乱码内容"口口口口"之类的,不然StringBuffer.toString()得到的结果可能丢失内容
 
PS(Postscript):
囧,不应该用toCharArray(),然后利用数字的有位置特点来实现这个截取,被前一个创建此方法的人影响了!直接用substring就好了,问题是之前用substring也是会丢失内容,所以我就采用StringBuffer,估计是接受响应结果使用StringBuffer.append(str + "\n")有问题,应该是StringBuffer.append(str),改成这样后,使用substring没有出现问题。喔,等待,刚测试,不是StringBuffer.append(str + "\n")造成substring截取内容丢失,还是乱码问题!需要截取的内容中不要有乱码!
 
附上代码:
package com.dafsdfsd.core.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException; import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.junit.Test; import com.dafsdfsd.core.common.PorpertiesConfig;
import com.dafsdfsd.core.utils.StringUtils;
import com.dafsdfsd.core.utils.xml.XmlUtil4Jdom; public class SendMessageToCore {
private static Logger logger = Logger.getLogger(SendMessageToCore.class); /**
* 核心返回报文中状态代码节点
*/
public static final String MESSAGE_STATUS_CODE = "MessageStatusCode";
/**
* 核心返回报文中状态描述节点
*/
public static final String MESSAGE_STATUS_DESCRIPTION = "MessageStatusDescription";
/**
* 核心返回报文中表示成功的代码
*/
public static final String CORE_RETURN_CODE_SUCCESS = "0001"; /**
* 发送报文到核心系统<br><pre>
* 核心接收GBK编码的报文,在调用这个方法之前应该将报文转换为GBK的编码 <br>
* 创建时间:2013-5-30 下午04:21:15 </pre>
* @param message 发送到核心的报文
* @return String 核心返回的报文
* @throws 异常类型 说明
*/
public static String sendMessage(String message) throws Exception {
logger.info("收到的报文内容是:" + message); String coreAddress = PorpertiesConfig.getProperty("core.socketAddress");
String corePortString = PorpertiesConfig.getProperty("core.socketPort"); Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
BufferedWriter bout = new BufferedWriter(new FileWriter(new File("G:/test.txt")));
BufferedWriter bout1 = new BufferedWriter(new FileWriter(new File("G:/test1.txt")));
// 收到的报文
StringBuffer stringBuffer = new StringBuffer();
String receiveString = null;
if (coreAddress != null && corePortString != null) {
int corePort = Integer.parseInt(corePortString);
try {
socket = new Socket(coreAddress, corePort);
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
out.println(message);
out.flush(); in = new BufferedReader(new InputStreamReader(socket.getInputStream(), XmlUtil4Jdom.GBK_ENCODING)); while ((message = in.readLine()) != null) {
// bout.write(message);
stringBuffer.append(message + "\n");
// stringBuffer.append(message);
} // BufferedReader流已指定编码输出,这里不需要再次转码了
// receiveString = new String(stringBuffer.toString().getBytes(XmlUtil4Jdom.GBK_ENCODING), XmlUtil4Jdom.GBK_ENCODING);
receiveString = stringBuffer.toString();
bout.write(receiveString); } catch (UnknownHostException e) {
logger.error("没有找到核心的服务器", e);
throw new Exception("没有找到核心的服务器", e);
} catch (IOException e) {
logger.error("与核心服务器通信出现异常", e);
throw new Exception("与核心服务器通信出现异常", e);
} finally {
if (out != null)
out.close();
if (in != null)
in.close();
if (bout != null)
bout.close();
}
} // receiveString = stringBuffer.toString();
// logger.info("核心返回的原始内容是:" + receiveString); String msgString = null;
if(null != receiveString && !receiveString.isEmpty()){ msgString = getXmlContent(receiveString); // int msgLength = Integer.parseInt(receiveString.substring(0, 6).trim()); // 前12位为报文长度和接口代码
// msgString = substring4CharArray(receiveString, 12, msgLength);
// msgString = receiveString.replaceFirst(msgLength, "");
// msgString = receiveString.substring(12);
// byte[] msg = msgString.getBytes(XmlUtil4Jdom.GBK_ENCODING);
//
// byte[] newMsg = new byte[msgLength];
// for (int i = 0; i < msgLength; i++) {
// newMsg[i] = msg[i];
// }
//
// msgString = new String(newMsg // logger.info("将核心返回的报文内容做编码转换及长度截取之后的结果:" + msgString);
logger.info("将核心返回的报文内容做编码转换及长度截取之后的结果:已处理");
} try {
bout1.write(msgString);
if (bout1 != null)
bout1.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} Document doc = DocumentHelper.parseText(msgString);
return msgString;
} public static String getXmlContent(String src) {
// StringBuffer sb = new StringBuffer();
String rs = null;
try {
// byte[] byteArray = null;
// char[] charArray = null;
// byteArray = src.getBytes(XmlUtil4Jdom.GBK_ENCODING);
// charArray = src.toCharArray();
// System.out.println(src.length());
// System.out.println(charArray.length);
// System.out.println(byteArray.length);
// System.out.println(src.charAt(1));
// System.out.println(src.charAt(src.length() - 2));
// System.out.println(src.charAt(src.length() - 1)); // 获取代码内容
String srcCode = org.apache.commons.lang.StringUtils.substring(src, 0, 12);
System.out.println(srcCode); // 获取xml内容
rs = org.apache.commons.lang.StringUtils.substring(src, 12, src.lastIndexOf(">") + 1);
// return src;
// charArray = src.toCharArray();
// for (int i = 0; i < charArray.length; i++) {
// sb.append(charArray[i]);
// } // System.out.println();
// System.out.println();
// System.out.println();
// System.out.println(src.length());
// System.out.println(charArray.length);
// System.out.println(byteArray.length); //String
// for (int i = 0; i < src.length(); i++) {
//// sb.append(charArray[i]);
//// sb.append(src.charAt(i));
// char s = src.charAt(i);
//// System.out.println(s);
// sb.append(s);
// } //byte
// for (int i = 0; i < byteArray.length; i++) {
// sb.append((char)byteArray[i]);
// }
// return new String(byteArray, XmlUtil4Jdom.GBK_ENCODING); // System.out.println();
// System.out.println();
// System.out.println();
// System.out.println(src.charAt(src.length() - 3));
// System.out.println(src.charAt(src.length() - 2));
// System.out.println(src.charAt(src.length() - 1)); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rs;
} @Test
public void test() {
StringBuffer buffer = new StringBuffer();
FileReader fr = null;
BufferedReader br = null;
try {
// fr = new FileReader("E:/workspace3/i-myproject/b_LOG/temp.xml");
fr = new FileReader("G:/workspace/i-myproject/temp.xml");
br = new BufferedReader(fr);
String content = br.readLine();
while (content != null) {
buffer.append(content);
content = br.readLine();
}
String msg = buffer.toString();
sendMessage(new String(msg.getBytes(), XmlUtil4Jdom.GBK_ENCODING));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
br.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }

Java 使用StringBuffer注意的更多相关文章

  1. JAVA String,StringBuffer与StringBuilder的区别??

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  2. Java String StringBuffer StringBuilder

    String  字符串常量存储在常量区,每次追加操作会创建新的对象: StringBuffer  字符串变量  线程安全 在堆上创建,每次追加操作在原对象上进行操作:  速度 StringBuffer ...

  3. 【转】JAVA的StringBuffer类

    [转]JAVA的StringBuffer类    StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBu ...

  4. Java源码学习 -- java.lang.StringBuilder,java.lang.StringBuffer,java.lang.AbstractStringBuilder

    一直以来,都是看到网上说“ StringBuilder是线程不安全的,但运行效率高:StringBuffer 是线程安全的,但运行效率低”,然后默默记住:一个是线程安全.一个线程不安全,但对内在原因并 ...

  5. Java之StringBuffer,StringBuilder,Math,Date,SimpleDateFormat,UUID,File

    java.lang 类 StringBuffer java.lang.Object java.lang.StringBuffer 所有已实现的接口: Serializable, Appendable, ...

  6. Java基础-StringBuffer类与StringBuilder类简介

    Java基础-StringBuffer类与StringBuilder类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.StringBuffer类 在学习过String类之后 ...

  7. Java 中StringBuffer与StringBuilder区别(转)及String类的一些基本操作代码

    String 字符串常量StringBuffer 字符串变量(线程安全)  多个线程访问时,不会产生问题(Synchronized)StringBuilder 字符串变量(非线程安全) 多个线程访问时 ...

  8. Java中StringBuffer类

    StringBuffer: 线程安全的可变字符串. StringBuffer和String的区别?前者长度和内容可变,后者不可变.如果使用前者做字符串的拼接,不会浪费太多的资源. StringBuff ...

  9. java之StringBuffer类详解

    StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...

  10. Java api 入门教程 之 JAVA的StringBuffer类

    StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存 ...

随机推荐

  1. linux系统——etc下的profile文件

    /etc/profile文件 /etc/profile是全局的,适用于所有的shell.在刚登录Linux时,首先启动 /etc/profile 文件. profile文件会告诉shell使用什么语言 ...

  2. ionic2 jpush

    ionic2 为ionic2调用极光插件提供符合angular2及TS的调用方式 install 先安装官方的cordova插件 $ cordova plugin add jpush-phonegap ...

  3. 如何在Ionic2项目中使用第三方JavaScript库

    onic的官网放出一记大招Ionic and Typings,来介绍如何在Ionic2项目中使用第三方JavaScript库. 因为在前阵子正好想用一个非常有名的第三方JS库ChartJs来实现一些东 ...

  4. 使用iview如何使左上的添加按钮和右上的搜索框和边框对齐

    使用iview如何使左上的添加按钮和右上的搜索框和边框对齐呢? 效果如下: 使用iview自带的Grid 栅格进行布局,但是由于按钮和搜索框的大小不正好是一个栅格的宽度,所以不是很好跳转,且栅格也不支 ...

  5. 检测字符串当中x与o的数目是否相等

    题目如上 答案 function XO(str) { var arr = str.split(""), xCount = , oCount = ; var reX = /x/i, ...

  6. JavaScript文本收缩展开 showdetail

    原文发布时间为:2009-11-15 -- 来源于本人的百度文章 [由搬家工具导入] <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tran ...

  7. Berkeley DB Java Edition 简介

    一.             简介        Berkeley DB Java Edition (JE)是一个完全用JAVA写的,它适合于管理海量的,简单的数据. l         能够高效率的 ...

  8. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---13

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  9. layui 的Tab选项卡

    http://www.layui.com/doc/element/tab.html <#--start--> <div class="layui-tab layui-tab ...

  10. Facebook为什么使用PHP编程语言?

    当日本计算机科学家松本行弘决定创造一种名叫 Ruby (这种技术支撑了 Twitter.Hulu以及其他许多现代 Web 流行网站) 的程序语言时,他是从 1966 年一部名为 Babel-17 的科 ...