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. Ubuntu 硬盘大小扩展

    注:途中所有图均为配置好补的截图,部分来自其它网页. 1.选择硬盘(SCSI) 2.点击扩展,在弹出框填写期望的硬盘大小(不能比原硬盘大小容量小) 3.进入虚拟机,安装GParted. 命令:sudo ...

  2. CDOJ 1256 二维前缀和处理

    昊昊喜欢运动 他NN 天内会参加MM 种运动(每种运动用一个[1,m][1,m] 的整数表示) 舍友有QQ 个问题 问昊昊第ll 天到第rr 天参加了多少种不同的运动 Input 输入两个数NN , ...

  3. php合并图片

    <?php class image{ /** * @param string $backgroundImage 背景图 * @param string $smallImage 小图 * @par ...

  4. THUWC 2018(游记)

    这次是在雅礼洋湖中学举行的,一所2017年才创办的学校,新的学校, 貌似有些危险,积雪过多屋顶上的冰块砸下来,很容易砸到人, 听说最近就有一个人被砸死了. Day1 昨天睡的比较迟,12点吧,今天早上 ...

  5. sooket数据成传输压缩

    样压缩不以文件为基础的数据 Q: 回答了两个使用Java进行数据压缩的问题. 第一个问题是: 我怎样才能压缩那些不在文件中的数据. 第二个问题是: 我以极大的热情阅读了Todd Sundsted的&q ...

  6. LeetCode OJ--Merge Intervals @

    https://oj.leetcode.com/problems/merge-intervals/ 合并区间 //排序 sort(intervals.begin(),intervals.end(),C ...

  7. LeetCode OJ--4Sum *

    https://oj.leetcode.com/problems/4sum/ 在一个数列中,找出所有的4个数,它们的和是target. class Solution { public: vector& ...

  8. 使用PyQt4制作一个正则表达式测试小工具

    最近在做一些网络爬虫的时候,会经常用到正则表达式.为了写出正确的正则表达式,我经常在这个网站上进行测试:Regex Tester.这个页面上面一个输入框输入正则表达式,下面一个输入框输入测试数据,上面 ...

  9. failed to obtain a cell from its dataSource 问题处理

    最近在处理bugly问题的时候,总会看到回话列表有奔溃,但是由于没有啥具体的细节原因也无从下手. 只知道ConversationListViewController这个类的奔溃,报的问题是这个,也只有 ...

  10. python笔记5:函数式编程

    5 函数式编程(即高阶函数,将函数作为参数传入) map(): map()函数接收两个参数,一个是传入函数,一个是Iterable,map将传入函数依次作用到序列的每个元素,并把结果作为新的Itera ...