Java复制整个文件,不带双引号
我有一种使用缓冲区将整个文件从一个目标复制到另一个目标的方法:Java复制整个文件,不带双引号,java,inputstream,outputstream,Java,Inputstream,Outputstream,我有一种使用缓冲区将整个文件从一个目标复制到另一个目标的方法: InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest); byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.close(
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
该文件为csv格式:
"2280B_TJ1400_001","TJ1400_Type-7SR","192.168.50.76","Aries SDH","6.0","192.168.0.254",24,"2280B Cyberjaya","Mahadzir Ibrahim"
但正如你所看到的,它里面有引号。是否可以根据我现有的代码删除它们
输出应如下所示:
2280B_TJ1400_001,TJ1400_Type-7SR,192.168.50.76,Aries SDH,6.0,192.168.0.254,24,2280B Cyberjaya,Mahadzir Ibrahim
不确定这是不是一个好主意,但你可以这样做:
while ((len = in.read(buf)) > 0) {
String temp = new String(buf);
temp = temp.replaceAll("\"","");
buf = temp.getBytes();
len = temp.length();
out.write(buf, 0, len);
}
如果使用,则可以使用readLine()
函数以字符串的形式读取文件内容。然后,您可以使用String
上的普通函数在将其写入输出之前对其进行操作。通过使用OutputStreamWriter
可以直接写入字符串
上述方法的一个优点是,您不必费心处理原始字节,这使您的代码更易于阅读,并且在特殊情况下更不容易出错
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(src)));
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(dest));
String line;
while ((line = in.readLine()) != null) {
String stringOut = line.replaceAll("\"", "");
out.write(stringOut);
}
in.close();
out.close();
请注意,这将删除所有“字符,而不仅仅是每个字符串开头和结尾的字符。为此,您可以使用StringTokenizer
,或更复杂的替换。对于我来说,我将读取字符串中之前的所有文件,然后去掉字符串中的“.”。然后将其写入dest文件
以字符串形式读取文件
我找到了这个。这可能不是最好的,这取决于您捕获所需错误的级别。但它已经足够有效;)
去掉“”
content = content.replaceAll('"', "");
将其从写入dest文件
这是针对Java7+的。
没有测试它,但它应该可以工作!不一定是好的样式,过滤二进制数据中的引号,但非常可靠
用您自己的InputStream包装原始InputStream,过滤掉双引号
我添加了一个怪癖:在MS Excel中,一个带引号的字段可能包含一个引号,然后它会自动转义,表示为两个双引号
InputStream in = new UnquotingInputStream(new FileInputStream(src));
/**
* Removes ASCII double quote from an InputStream.
* Two consequtive quotes stand for one quote: self-escaping like used
* by MS Excel.
*/
public class UnquotingInputStream extends InputStream {
private final InputStream in;
private boolean justHadAQuote;
public UnquotingInputStream(InputStream in) {
this.in = in;
}
@Override
public int read() throws IOException {
int c = in.read();
if (c == '\"') {
if (!justHadAQuote) {
justHadAQuote = true;
return read(); // Skip quote
}
}
justHadAQuote = false;
return c;
}
}
适用于所有使用ASCII作为子集的编码。所以不是:UTF-16或EBCDIC。它的可能副本使用csvreader,我认为它需要opencsv。如果我错了,请纠正我,但该库在jdk 1.6中不起作用(部署我的exe jar)这就是我使用缓冲区的原因。:)此解决方案不考虑字符编码,可能会导致异常和/或不需要的结果。@icza:是的,我理解,但想不出更好的解决方案。更好的解决方案是使用读取器
而不是正确转换字节的输入流“@icza:我不想更改OP的当前实现。我尝试过,但当有两个双引号时,它会停止复制。”,“”。我想我没有注意到这些空字段。谢谢你的回答……它起作用了,我添加了一个try-and-catch来处理任何错误异常。谢谢。”
Files.write(Paths.get("./duke.txt"), msg.getBytes());
InputStream in = new UnquotingInputStream(new FileInputStream(src));
/**
* Removes ASCII double quote from an InputStream.
* Two consequtive quotes stand for one quote: self-escaping like used
* by MS Excel.
*/
public class UnquotingInputStream extends InputStream {
private final InputStream in;
private boolean justHadAQuote;
public UnquotingInputStream(InputStream in) {
this.in = in;
}
@Override
public int read() throws IOException {
int c = in.read();
if (c == '\"') {
if (!justHadAQuote) {
justHadAQuote = true;
return read(); // Skip quote
}
}
justHadAQuote = false;
return c;
}
}