java 读取csv_Java读取CSV的常用方法 | 学步园

在项目开发中,我们经常需要读取csv的内容的操作。读取的逻辑并不复杂。主要是对有换行的,逗号,引号的处理恰当的话就没问题了。

下面作为memo,把在项目中的读取方法拷贝了过来。有了下面的这些方法,在CSV的读取和输出的时候都非常方便。

package com.han.csv.util;

import java.io.BufferedReader;

import java.io.FileInputStream;

import java.io.InputStreamReader;

import java.util.ArrayList;

public class CSVFileUtil {

// CSV文件编码

public static final String ENCODE = "UTF-8";

private FileInputStream fis = null;

private InputStreamReader isw = null;

private BufferedReader br = null;

public CSVFileUtil(String filename) throws Exception {

fis = new FileInputStream(filename);

isw = new InputStreamReader(fis, ENCODE);

br = new BufferedReader(isw);

}

// ==========以下是公开方法=============================

/**

* 从CSV文件流中读取一个CSV行。

*

* @throws Exception

*/

public String readLine() throws Exception {

StringBuffer readLine = new StringBuffer();

boolean bReadNext = true;

while (bReadNext) {

//

if (readLine.length() > 0) {

readLine.append("\r\n");

}

// 一行

String strReadLine = br.readLine();

// readLine is Null

if (strReadLine == null) {

return null;

}

readLine.append(strReadLine);

// 如果双引号是奇数的时候继续读取。考虑有换行的是情况。

if (countChar(readLine.toString(), '"', 0) % 2 == 1) {

bReadNext = true;

} else {

bReadNext = false;

}

}

return readLine.toString();

}

/**

*把CSV文件的一行转换成字符串数组。指定数组长度,不够长度的部分设置为null。

*/

public static String[] fromCSVLine(String source, int size) {

ArrayList tmpArray = fromCSVLinetoArray(source);

if (size < tmpArray.size()) {

size = tmpArray.size();

}

String[] rtnArray = new String[size];

tmpArray.toArray(rtnArray);

return rtnArray;

}

/**

* 把CSV文件的一行转换成字符串数组。不指定数组长度。

*/

public static ArrayList fromCSVLinetoArray(String source) {

if (source == null || source.length() == 0) {

return new ArrayList();

}

int currentPosition = 0;

int maxPosition = source.length();

int nextComma = 0;

ArrayList rtnArray = new ArrayList();

while (currentPosition < maxPosition) {

nextComma = nextComma(source, currentPosition);

rtnArray.add(nextToken(source, currentPosition, nextComma));

currentPosition = nextComma + 1;

if (currentPosition == maxPosition) {

rtnArray.add("");

}

}

return rtnArray;

}

/**

* 把字符串类型的数组转换成一个CSV行。(输出CSV文件的时候用)

*/

public static String toCSVLine(String[] strArray) {

if (strArray == null) {

return "";

}

StringBuffer cvsLine = new StringBuffer();

for (int idx = 0; idx < strArray.length; idx++) {

String item = addQuote(strArray[idx]);

cvsLine.append(item);

if (strArray.length - 1 != idx) {

cvsLine.append(',');

}

}

return cvsLine.toString();

}

/**

* 字符串类型的List转换成一个CSV行。(输出CSV文件的时候用)

*/

public static String toCSVLine(ArrayList strArrList) {

if (strArrList == null) {

return "";

}

String[] strArray = new String[strArrList.size()];

for (int idx = 0; idx < strArrList.size(); idx++) {

strArray[idx] = (String) strArrList.get(idx);

}

return toCSVLine(strArray);

}

// ==========以下是内部使用的方法=============================

/**

*计算指定文字的个数。

*

* @param str 文字列

* @param c 文字

* @param start 开始位置

* @return 个数

*/

private int countChar(String str, char c, int start) {

int i = 0;

int index = str.indexOf(c, start);

return index == -1 ? i : countChar(str, c, index + 1) + 1;

}

/**

* 查询下一个逗号的位置。

*

* @param source 文字列

* @param st 检索开始位置

* @return 下一个逗号的位置。

*/

private static int nextComma(String source, int st) {

int maxPosition = source.length();

boolean inquote = false;

while (st < maxPosition) {

char ch = source.charAt(st);

if (!inquote && ch == ',') {

break;

} else if ('"' == ch) {

inquote = !inquote;

}

st++;

}

return st;

}

/**

* 取得下一个字符串

*/

private static String nextToken(String source, int st, int nextComma) {

StringBuffer strb = new StringBuffer();

int next = st;

while (next < nextComma) {

char ch = source.charAt(next++);

if (ch == '"') {

if ((st + 1 < next && next < nextComma) && (source.charAt(next) == '"')) {

strb.append(ch);

next++;

}

} else {

strb.append(ch);

}

}

return strb.toString();

}

/**

* 在字符串的外侧加双引号。如果该字符串的内部有双引号的话,把"转换成""。

*

* @param item 字符串

* @return 处理过的字符串

*/

private static String addQuote(String item) {

if (item == null || item.length() == 0) {

return "\"\"";

}

StringBuffer sb = new StringBuffer();

sb.append('"');

for (int idx = 0; idx < item.length(); idx++) {

char ch = item.charAt(idx);

if ('"' == ch) {

sb.append("\"\"");

} else {

sb.append(ch);

}

}

sb.append('"');

return sb.toString();

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/417347.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

判断两颗树是否相同

tag: 二叉树 package com.zhaochao.tree;import java.util.Stack;/*** Created by zhaochao on 17/1/24.* 两颗树相等&#xff0c;意味着 对应节点的值相等&#xff0c;且具备相同的左右子树*/ public class JudgeSameTree {//recursion public boolean isSame(TreeNode rootA,…

C# XML格式化显示

/// <summary>/// XML格式化为文本显示/// </summary>/// <param name"str"></param>/// <returns></returns>public static string ShowXml(string str){MemoryStream mstream new MemoryStream();XmlTextWriter writer new …

C# CKEditor、CKFinder集成使用

1.裁剪&#xff08;ckeditor在\_Samples\ckeditor中&#xff09;2.添加引用&#xff1a;CKEditor.NET.dll、CKFinder.dll3.配置CKEditor&#xff1a;ckeditor/config.jsCKEDITOR.editorConfig function (config) {config.skin office2003;};4.使用CKEditor&#xff1a;<% …

tcp/ip四层和osi七层

转载于:https://www.cnblogs.com/mountian-lion/p/6353819.html

java的进程和线程_java进程和线程区别与不同

java进程和线程区别与不同。一、定义1.进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的一个独立单位。2.线程是进程的一个实体&#xff0c;是CPU调度和分派的基本单位&#xff0c;他是比进程更小的能独立运行的基本单位&…

【网络流24题----09】方格取数问题

问题描述&#xff1a;在一个有m*n 个方格的棋盘中&#xff0c;每个方格中有一个正整数。现要从方格中取数&#xff0c;使任意2 个数所在方格没有公共边&#xff0c;且取出的数的总和最大。试设计一个满足要求的取数算法。编程任务&#xff1a;对于给定的方格棋盘&#xff0c;按…

split 中文 java_Java String[] split() 方法

public class Test {public static void main(String args[]) {String str new String("Welcome-to-Itizixishi");System.out.println("- 分隔符返回值 :" );for (String retval: str.split("-")){System.out.println(retval);}System.out.prin…

C# JScript.Eval使用

using Microsoft.JScript;using Microsoft.JScript.Vsa;VsaEngine ve VsaEngine.CreateEngine();object obj Eval.JScriptEvaluate("(" strIn ")", ve);

做最好的自己——读书笔记

精彩片段 谁都渴望成功&#xff0c;但似乎谁都摸不准成功的脉络&#xff1b;与其裹挟在追逐成功的大军里茫然前行&#xff0c;还不如冷静下来&#xff0c;自己跟自己比上一比。 有一天&#xff0c;这个学生问我&#xff1a;“开复博士&#xff0c;我希望自己能像您一样成功。根…

teleport最新版不支持mysql_QA · tp4a/teleport Wiki · GitHub

常见问题安装部署问题Q&#xff1a;使用MySQL数据库&#xff0c;有时重启teleport服务后工作不正常。A&#xff1a;Teleport内建支持SQLite&#xff0c;因此 /etc/init.d/teleport 启动脚本没有加入对mysqld服务的依赖&#xff0c;导致有时teleport服务先于mysqld服务启动&…

js Ajax跨域访问

-----------------------index.html<html><head><title>JQuery Ajax跨域访问</title><script src"jquery.js" type"text/javascript"></script><script type"text/javascript">$(function () {var oB…

拆分-洛谷P2745 [USACO5.3]窗体面积Window Area

https://www.luogu.org/problem/show?pid2745 本来因为会WA的&#xff0c;结果AC了&#xff0c;啊哈哈哈哈哈哈哈哈哈 因为题目要求我们要把一个个平面有先后关系&#xff0c;那么我们就搞一个队列嘛&#xff0c;每次询问时&#xff0c;不断把平面上升就好了&#xff1b; 但…

java搭建tcp客户端_【Java学习笔记】TCP客户端/服务器端

客户端&#xff1a;import java.net.Socket;import java.net.InetAddress;import java.net.UnknownHostException;import java.io.OutputStream;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;impor…

SQLServer表分区

use Test--1分区函数CREATE PARTITION FUNCTION IDRange(int) AS RANGE LEFT FOR VALUES ( 99999999,199999999, 299999999) USE master--2然后我们需要添加相应的文件组 .我使用的是TestData文件组.ALTER DATABASE Test ADD FILEGROUP [TestData] ALTER DATABASE TestADD FILE…