gpt4 book ai didi

tail n行文件的Java代码相当于unix中的tail命令

转载 作者:行者123 更新时间:2023-12-05 09:00:05 27 4
gpt4 key购买 nike

以下是为拖尾“n”行文件编写的代码。

 <code>

import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;

class TailCommand {
public static void main(String args[]) {
int j;
try {
/*
* Receive file name and no of lines to tail as command line
* argument
*/
RandomAccessFile randomFile = new RandomAccessFile(args[0], "r");
long numberOfLines = Long.valueOf(args[1]).longValue();
long lineno = 0;
String str;
String outstr;
StringBuilder sb = new StringBuilder();
Map<Long, String> strmap = new HashMap<Long, String>();
while ((str = randomFile.readLine()) != null) {
strmap.put(lineno + 1, str);
lineno++;
}
System.out.println("Total no of lines in file is " + lineno);
long startPosition = lineno - numberOfLines;
while (startPosition <= lineno) {
if (strmap.containsKey(startPosition)) {
// System.out.println("HashMap contains "+ startPosition
// +" as key");
outstr = (String) strmap.get(startPosition);
sb.append(outstr);
System.out.println(outstr);
}
startPosition++;
}
// Collection coll = strmap.values();
// System.out.println(coll+"size"+strmap.size());
// System.out.println(sb);
} catch (Exception e) {
e.printStackTrace();
}
}
}

我使用了以下方法:文件和要尾部的行数作为命令行参数接收

  1. 使用 readLine 方法获取文件中的总行数
  2. 为每个 readLine 调用使用增量器
  3. 将这个增量器和 readLine 方法返回的字符串存储在一个 Hash Map 中
  4. 结果整个文件存储在 HashMap 中
  5. 现在您可以使用散列映射键从特定行检索文件值
  6. 您可以使用 stringbuilder 打印特定行的选择

我的疑问,

我的方法是否有效,我可以将这种方法用于大小大于 10MB 的大文件吗?如果更多的人必须同时从同一个文件中拖尾,我需要做哪些改进?我也可以对较大的文件使用 StringBuilder 吗?

最佳答案

正如我在对 djna 的回答的评论中提到的,你这样做的效率不高:

  • 您正在阅读整个文件。如果文件很大而 n 行很小,那么您只是在浪费时间、I/O 以及您拥有的一切。
  • 此外,您还在浪费内存。
  • 没有缓冲(除了 RandomAccessFile#readLine() 可能会或可能不会提供的东西),这也可能导致一些速度变慢。

因此,我要做的是从末尾开始以 block 的形式向后读取文件并分别处理这些 block 。

RandomAccessFile raf = new RandomAccessFile(new File(file), "r");
List<String> lines = new ArrayList<String>();

final int chunkSize = 1024 * 32;
long end = raf.length();
boolean readMore = true;
while (readMore) {
byte[] buf = new byte[chunkSize];

// Read a chunk from the end of the file
long startPoint = end - chunkSize;
long readLen = chunkSize;
if (startPoint < 0) {
readLen = chunkSize + startPoint;
startPoint = 0;
}
raf.seek(startPoint);
readLen = raf.read(buf, 0, (int)readLen);
if (readLen <= 0) {
break;
}

// Parse newlines and add them to an array
int unparsedSize = (int)readLen;
int index = unparsedSize - 1;
while (index >= 0) {
if (buf[index] == '\n') {
int startOfLine = index + 1;
int len = (unparsedSize - startOfLine);
if (len > 0) {
lines.add(new String(buf, startOfLine, len));
}
unparsedSize = index + 1;
}
--index;
}

// Move end point back by the number of lines we parsed
// Note: We have not parsed the first line in the chunked
// content because could be a partial line
end = end - (chunkSize - unparsedSize);

readMore = lines.size() < linesToRead && startPoint != 0;
}

// Only print the requested number of lines
if (linesToRead > lines.size()) {
linesToRead = lines.size();
}

for (int i = linesToRead - 1; i >= 0; --i) {
pw.print(lines.get(i));
}

关于tail n行文件的Java代码相当于unix中的tail命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6888001/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com