mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
add LineCounter
This commit is contained in:
parent
8ccdf408f9
commit
c3aabfcd14
@ -23,6 +23,7 @@ import org.dromara.hutool.core.io.resource.FileResource;
|
||||
import org.dromara.hutool.core.io.resource.Resource;
|
||||
import org.dromara.hutool.core.io.resource.ResourceUtil;
|
||||
import org.dromara.hutool.core.io.stream.BOMInputStream;
|
||||
import org.dromara.hutool.core.io.stream.LineCounter;
|
||||
import org.dromara.hutool.core.io.unit.DataSizeUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.lang.Console;
|
||||
@ -551,7 +552,7 @@ public class FileUtil extends PathUtil {
|
||||
* @since 5.7.22
|
||||
*/
|
||||
public static int getTotalLines(final File file) {
|
||||
return getTotalLines(file, 1024);
|
||||
return getTotalLines(file, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -563,46 +564,12 @@ public class FileUtil extends PathUtil {
|
||||
* @return 该文件总行数
|
||||
* @since 5.8.28
|
||||
*/
|
||||
public static int getTotalLines(final File file, int bufferSize) {
|
||||
public static int getTotalLines(final File file, final int bufferSize) {
|
||||
if (false == isFile(file)) {
|
||||
throw new IORuntimeException("Input must be a File");
|
||||
}
|
||||
if (bufferSize < 1) {
|
||||
bufferSize = 1024;
|
||||
}
|
||||
try (final InputStream is = getInputStream(file)) {
|
||||
final byte[] c = new byte[bufferSize];
|
||||
int readChars = is.read(c);
|
||||
if (readChars == -1) {
|
||||
// 空文件,返回0
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 起始行为1
|
||||
// 如果只有一行,无换行符,则读取结束后返回1
|
||||
// 如果多行,最后一行无换行符,最后一行需要单独计数
|
||||
// 如果多行,最后一行有换行符,则空行算作一行
|
||||
int count = 1;
|
||||
while (readChars == bufferSize) {
|
||||
for (int i = 0; i < bufferSize; i++) {
|
||||
if (c[i] == CharUtil.LF) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
readChars = is.read(c);
|
||||
}
|
||||
|
||||
// count remaining characters
|
||||
while (readChars != -1) {
|
||||
for (int i = 0; i < readChars; i++) {
|
||||
if (c[i] == CharUtil.LF) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
readChars = is.read(c);
|
||||
}
|
||||
|
||||
return count;
|
||||
try (final LineCounter lineCounter = new LineCounter(getInputStream(file), bufferSize)) {
|
||||
return lineCounter.getCount();
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2024. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.io.stream;
|
||||
|
||||
import org.dromara.hutool.core.io.IORuntimeException;
|
||||
import org.dromara.hutool.core.text.CharUtil;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 行数计数器
|
||||
*
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class LineCounter implements Closeable {
|
||||
|
||||
private final InputStream is;
|
||||
private final int bufferSize;
|
||||
|
||||
private int count = -1;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param is 输入流
|
||||
* @param bufferSize 缓存大小,小于1则使用默认的1024
|
||||
*/
|
||||
public LineCounter(final InputStream is, final int bufferSize) {
|
||||
this.is = is;
|
||||
this.bufferSize = bufferSize < 1 ? 1024 : bufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取行数
|
||||
*
|
||||
* @return 行数
|
||||
*/
|
||||
public int getCount() {
|
||||
if (this.count < 0) {
|
||||
try {
|
||||
this.count = count();
|
||||
} catch (final IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
return this.count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (null != this.is) {
|
||||
this.is.close();
|
||||
}
|
||||
}
|
||||
|
||||
private int count() throws IOException {
|
||||
final byte[] c = new byte[bufferSize];
|
||||
int readChars = is.read(c);
|
||||
if (readChars == -1) {
|
||||
// 空文件,返回0
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 起始行为1
|
||||
// 如果只有一行,无换行符,则读取结束后返回1
|
||||
// 如果多行,最后一行无换行符,最后一行需要单独计数
|
||||
// 如果多行,最后一行有换行符,则空行算作一行
|
||||
int count = 1;
|
||||
while (readChars == bufferSize) {
|
||||
for (int i = 0; i < bufferSize; i++) {
|
||||
if (c[i] == CharUtil.LF) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
readChars = is.read(c);
|
||||
}
|
||||
|
||||
// count remaining characters
|
||||
while (readChars != -1) {
|
||||
for (int i = 0; i < readChars; i++) {
|
||||
if (c[i] == CharUtil.LF) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
readChars = is.read(c);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user