`
阅读更多

java 如何无损读取文本文件呢?

以下是有损

@Deprecated
	public static String getFullContent(File file, String charset) {
		BufferedReader reader = null;
		if (!file.exists()) {
			System.out.println("getFullContent: file(" + file.getAbsolutePath()
					+ ") does not exist.");
			return null;
		}
		if (charset == null) {
			charset = SystemHWUtil.CHARSET_ISO88591;
		}
		try {
			reader = getBufferReaderFromFile(file, charset);
			return getFullContent(reader);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} finally {
			if (null != reader) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

public static BufferedReader getBufferReaderFromFile(File file,
			String charset) throws FileNotFoundException {
		InputStream ss = new FileInputStream(file);
		InputStreamReader ireader;
		BufferedReader reader = null;
		try {
			if (charset == null) {
				ireader = new InputStreamReader(ss,
						SystemHWUtil.CHARSET_ISO88591);
			} else {
				ireader = new InputStreamReader(ss, charset);
			}
			reader = new BufferedReader(ireader);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return reader;
	}

/**
	 * have closed reader
	 * 
	 * @param reader
	 * @return
	 */
	@Deprecated
	public static String getFullContent(BufferedReader reader) {
		StringBuilder sb = new StringBuilder();
		String readedLine = null;
		try {
			while ((readedLine = reader.readLine()) != null) {
				sb.append(readedLine);
				sb.append(SystemHWUtil.CRLF);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		String content = sb.toString();
		int length_CRLF = SystemHWUtil.CRLF.length();
		if (content.length() <= length_CRLF) {
			return content;
		}
		return content.substring(0, content.length() - length_CRLF);//
	}

 测试:

@Test
	public void test_getFullContent(){
		String filepath="D:\\bin\\config\\conf_passwd.properties";
		try {
			InputStream in =new FileInputStream(filepath);
			System.out.print(FileUtils.getFullContent(filepath, "UTF-8"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

介绍三种无损读取的方式

方式一:使用InputStreamReader,指定编码

/***
	 * 指定字符编码,无损地读取文本文件.
	 * 
	 * @param in
	 *            : 输入流,会关闭
	 * @param charset
	 *            : 字符编码
	 * @return
	 * @throws IOException
	 */
	public static String getFullContent3(InputStream in, String charset)
			throws IOException {
		StringBuffer sbuffer = new StringBuffer();
		InputStreamReader inReader;
		//设置字符编码
		inReader = new InputStreamReader(in, charset);
		char[] ch = new char[SystemHWUtil.BUFF_SIZE_1024];
		int readCount = 0;
		while ((readCount = inReader.read(ch)) != -1) {
			sbuffer.append(ch, 0, readCount);
		}
		inReader.close();
		in.close();
		return sbuffer.toString();
	}

 测试:

@Test
	public void test_getFullContent3(){
		String filepath="D:\\bin\\config\\conf_passwd.properties";
		try {
			InputStream in =new FileInputStream(filepath);
			System.out.print(FileUtils.getFullContent3(in, "UTF-8"));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

 

方式二:先读取出字节数组,再使用String的构造方法

public static String getFullContent4(InputStream in, String charset) throws IOException{
		byte[]bytes=FileUtils.readBytes3(in);
		return new String(bytes,charset);
	}

/***
	 * Has been tested
	 * 
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static byte[] readBytes3(InputStream in) throws IOException {
		BufferedInputStream bufin = new BufferedInputStream(in);
		int buffSize = BUFFSIZE_1024;
		ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize);

		// System.out.println("Available bytes:" + in.available());

		byte[] temp = new byte[buffSize];
		int size = 0;
		while ((size = bufin.read(temp)) != -1) {
			out.write(temp, 0, size);
		}
		bufin.close();
		in.close();
		byte[] content = out.toByteArray();
		out.flush();
		out.close();
		return content;
	}

 

 

方式三:使用System.arraycopy,所以效率不高,因为有拷贝操作(不推荐

public static String getFullContent2(InputStream in, String charset)
			throws IOException {
		int step = BUFFSIZE_1024;
		BufferedInputStream bis = new BufferedInputStream(in);

		// Data's byte array
		byte[] receData = new byte[step];

		// data length read from the stream
		int readLength = 0;

		// data Array offset
		int offset = 0;

		// Data array length
		int byteLength = step;

		while ((readLength = bis.read(receData, offset, byteLength - offset)) != -1) {
			// Calculate the current length of the data
			offset += readLength;
			// Determine whether you need to copy data , when the remaining
			// space is less than step / 2, copy the data
			if (byteLength - offset <= step / 2) {
				byte[] tempData = new byte[receData.length + step];
				System.arraycopy(receData, 0, tempData, 0, offset);
				receData = tempData;
				byteLength = receData.length;
			}
		}

		return new String(receData, 0, offset, charset);
	}

 

总结:推荐使用方式一方式二

相关方法见附件中com.io.hw.file.util.FileUtils类

3
5
分享到:
评论
12 楼 hw1287789687 2013-12-21  
在世界的中心呼喚愛 写道
看懂了,楼主应该是说,字节读取是无损的!!

嗯,就是这个意思
11 楼 在世界的中心呼喚愛 2013-12-21  
看懂了,楼主应该是说,字节读取是无损的!!
10 楼 在世界的中心呼喚愛 2013-12-21  
hw1287789687 写道
Grumpy 写道
太高深了,用readLine()居然是有损。。。那我用read(char[]),可以把所有字符都读出来,应该能算是无损了吧。。。

用readLine() 的话,会少一个换行或多一个换行(没法精确控制),反正没法保证读取出来的跟原来的文本文件内容完全一样(使用equals时可能返回false)。
用read(char[])可以达到无损的目标


API中说的很清楚,readLine就是读取行。。
9 楼 Grumpy 2013-12-20  
hw1287789687 写道
Grumpy 写道
太高深了,用readLine()居然是有损。。。那我用read(char[]),可以把所有字符都读出来,应该能算是无损了吧。。。

用readLine() 的话,会少一个换行或多一个换行(没法精确控制),反正没法保证读取出来的跟原来的文本文件内容完全一样(使用equals时可能返回false)。
用read(char[])可以达到无损的目标


如果Reader.read(char[])是无损,你这3个方法不就都是多此一举,而且要想一个字节不漏的拿到数据,我用InputStream.read(byte[])可以确保一个字节都不漏,更安全。换行一般都是用来区分段落,readLine可以使你减少解析步骤,居然被说成是有损。。。
8 楼 hw1287789687 2013-12-20  
Grumpy 写道
太高深了,用readLine()居然是有损。。。那我用read(char[]),可以把所有字符都读出来,应该能算是无损了吧。。。

用readLine() 的话,会少一个换行或多一个换行(没法精确控制),反正没法保证读取出来的跟原来的文本文件内容完全一样(使用equals时可能返回false)。
用read(char[])可以达到无损的目标
7 楼 Grumpy 2013-12-20  
太高深了,用readLine()居然是有损。。。那我用read(char[]),可以把所有字符都读出来,应该能算是无损了吧。。。
6 楼 hjz1034979852 2013-12-20  
啥莫叫做无损
5 楼 hw1287789687 2013-12-20  
canghailan 写道
没看明白有损无损啥意思。有损是指BufferedReader.readLine()时丢掉的换行吗?文件大小已知,所以字节缓冲区的大小就可以确定,不需要用固定缓冲区大小。如果用nio的话,会更方便一些。
public static String readText(File file, String charset) throws IOException {
	FileChannel fileChannel = null;
	try {
		fileChannel = new FileInputStream(file).getChannel();
		ByteBuffer byteBuffer = fileChannel.map(MapMode.READ_ONLY, 0,
				fileChannel.size());
		CharBuffer charBuffer = Charset.forName(charset).decode(byteBuffer);
		return charBuffer.toString();
	} finally {
		if (fileChannel != null) {
			fileChannel.close();
		}
	}
}

1楼说得对。有损是指BufferedReader.readLine()时丢掉的换行
4 楼 w156445045 2013-12-19  
不明觉厉。
3 楼 Grumpy 2013-12-19  
没看明白lz说的是什么。
能不能从文件中读出String,是由文件中存储的数据类型决定的,如果存储的是字符类型,可以用BufferedReader.readLine()直接读取字符串,如果是字节类型,不管你是用Reader读还是用InputStream读出字节数组再转成String,都是不行的,即使读出来也是乱码。
另外编码跟文件的读取没关系,只跟显示有关系,编码不正确会显示成乱码,仅此而已。
可以通过String.getBytes(String encoding)后再new String (byte [] data, int start, int length, final String encoding)进行转码。
2 楼 canghailan 2013-12-19  
其实方式三的效率比方式二要高,
1.ByteArrayOutputStream.write 会调用 System.arraycopy 拷贝一遍。
2.ByteArrayOutputStream 自动扩容时也会调用 System.arraycopy 拷贝一遍。
3.ByteArrayOutputStream.toByteArray 又会调用 System.arraycopy 拷贝一遍。
4.ByteArrayOutputStream 中有不必要的同步和index检查的开销。

方式二在最好情况要拷贝2次,最坏情况要拷贝3+n次。
方式三在最好情况要拷贝1次,最坏情况要拷贝2+n次。
n为扩容次数。
1 楼 canghailan 2013-12-19  
没看明白有损无损啥意思。有损是指BufferedReader.readLine()时丢掉的换行吗?文件大小已知,所以字节缓冲区的大小就可以确定,不需要用固定缓冲区大小。如果用nio的话,会更方便一些。
public static String readText(File file, String charset) throws IOException {
	FileChannel fileChannel = null;
	try {
		fileChannel = new FileInputStream(file).getChannel();
		ByteBuffer byteBuffer = fileChannel.map(MapMode.READ_ONLY, 0,
				fileChannel.size());
		CharBuffer charBuffer = Charset.forName(charset).decode(byteBuffer);
		return charBuffer.toString();
	} finally {
		if (fileChannel != null) {
			fileChannel.close();
		}
	}
}

相关推荐

    java读取文件中文乱码

    3. `InputStreamReader`与`BufferedReader`:Java通常使用`InputStreamReader`和`BufferedReader`组合来读取文本文件。`InputStreamReader`需要指定一个字符集,这样它才能将字节流转换为字符流。 4. 指定编码:在...

    Huffman 霍夫曼 无损压缩 算法实现 java

    - `binview`工具可能是一个专门用来查看`.huff`文件内容的程序,它能够解析和显示霍夫曼编码后的二进制数据,便于理解和调试压缩结果。 总的来说,通过Java实现的霍夫曼无损压缩算法,可以有效地压缩文本数据,...

    Java下载m3u8文件列表中的TS文件到本地工具类

    2. 智能排序:根据M3U8文件的顺序逻辑,精确无误地将各个TS文件按序下载,确保视频内容完整无损。 3. 高性能高稳定性:依托流读写,实现高速下载,充分利用网络带宽,提高下载速度,保障下载过程稳定流畅。 4. 灵活...

    java实现霍夫曼树压缩文本文件和解压

    在实现这个过程中,Java提供了一些关键类和接口,如`FileReader`和`BufferedReader`用于读取文本文件,`PriorityQueue`用于构建霍夫曼树,`OutputStream`和`InputStream`用于文件的读写操作,以及`BitOutputStream`...

    javatcp传送文件

    由于大文件可能无法一次性全部加载到内存,因此通常会采用分块读写的方式,即每次读取或写入一部分文件内容,直到整个文件传输完毕。 在二进制文件传输中,我们需要注意以下几点: 1. 使用BufferedInputStream和...

    java算法,实现压缩及解压缩

    - 循环读取文件内容并写入压缩流。 - 关闭文件输入流。 ```java for (int i = 0; i ; i++) { //... ZipEntry entry = new ZipEntry(files[i].getName()); out.putNextEntry(entry); while ((count = origin....

    Java提取IPA中的png文件, 并进行解码还原png图片

    可以使用Java的`java.util.zip`包中的`ZipFile`类来读取和遍历IPA中的内容。 2. **定位PNG图片**:在IPA文件的资源目录下,找到包含PNG图像的路径。这通常涉及到对IPA内部的manifest.plist文件解析,以了解资源的...

    java IO以追加方式写文件FileWrite

    在Java编程语言中,`FileWriter`类是用于处理文本文件写入操作的关键工具。当以追加方式写入文件时,我们希望在文件现有内容的末尾添加新的数据,而不是覆盖原有的内容。这种功能在日志记录、数据备份或者需要不断...

    java实现cad(dxf格式)转svg

    2. 使用DXF库解析DXF文件内容。 3. 遍历解析出的图形对象,创建相应的SVG元素。 4. 将SVG元素组合成一个完整的SVG文档字符串。 5. 使用Java的I/O类写入SVG文件。 在实际项目中,可能还需要考虑其他因素,比如颜色...

    哈夫曼编码实现压缩解压缩java

    哈夫曼编码是一种高效的数据编码方法,主要用于无损数据压缩,尤其在文本文件的压缩中表现出色。这种编码方式基于频率最小的字符用最短的二进制代码表示的原理,能够有效地减少数据存储和传输时的位数,从而达到压缩...

    java实现超大pdf文件转换word工具

    提取PDF中的文字,Apache PDFBox 提供了PDDocument和PDPageContentStream类,可以读取并解析PDF的文本内容。对于图像,PDFBox的PDImageXObject类可以帮助我们获取和保存PDF中的图像,确保无损转换。 至于提取PDF中...

    java实现计算一个文件的16位效验和

    - 逐字节读取文件内容到数组`a[]`中。 2. **处理奇数长度**: - 如果读取的文件长度是奇数,则需要在末尾添加一个0,使得数组长度为偶数,便于后续处理。 3. **组合成16位数值**: - 将每两个相邻的字节组合...

    JavaSwing文件Md5值计算器

    首先,程序会打开用户选择的文件并读取其内容,然后将这些内容转换为字节数组。接着,MD5算法对字节数组进行一系列的位操作、异或、加法和旋转,最终生成128位的散列值。这个过程通常由Java的java.security....

    java聊天程序 发送表情,文件等

    6. **聊天记录存储**:为了查看历史聊天记录,程序需要将聊天数据持久化存储,这可能涉及到数据库或文本文件的读写操作。合理的设计应该包括记录的查询、删除和更新功能。 7. **局域网搜索**:实现局域网内的用户...

    基于JAVA实现的文件压缩与解压缩实践(源代码+论文).zip

    在本项目中,我们主要探讨的是如何利用Java编程语言实现文件的压缩与解压缩功能。这个实践项目包含源代码和相关的论文,对于初级到进阶的Java开发者,或者是正在寻求毕业设计、课程设计、大作业或者工程实训项目的...

    算术算法压缩实现Java

    4. **输入输出处理**:为了实际读写文件,需要实现从字节流到符号的转换,以及从符号到字节流的转换。这通常涉及字节缓冲区和位操作。 5. **测试和优化**:编写测试用例,确保编码和解码的一致性,同时优化性能,如...

    java transfer filter 传输多种格式的文件

    Java Transfer Filter 是一种在Java应用程序中用于处理文件传输的技术,特别是在网络编程中,例如通过Socket进行文件发送和接收。这个技术允许程序过滤不同类型的文件,确保安全和有效的数据传输。以下是一些关于...

    java文件上传接口定义

    使用`InputStream`和`OutputStream`,我们可以控制文件的读写操作,确保数据完整无损地传输。 5. **文件命名与存储**: 上传的文件需要在服务器上存储,通常会自动生成一个唯一的文件名避免覆盖现有文件。可以使用...

    Java 图片压缩

    `imageToBase64`方法读取指定路径的图片文件,将其内容转换为字节数组,然后使用`Base64.getEncoder().encodeToString()`方法编码为Base64字符串。 至于下载和修改图片路径,Java的标准库没有提供直接的下载功能,...

Global site tag (gtag.js) - Google Analytics