BufferedReader 和流线 Java 8
BufferedReader and stream Line Java 8
使用 BufferedReader:我有一个文本文件,其中包含如下所列的类似行。
文本文件行示例:
ABC DEF EFG 1.2.3.3 MGM -Ba\
10.101.0.10
如何删除 -Ba
之后的行尾字符 \
并将下一个 line/Field 连接到第一行以获得新行,然后将其存储在数组中稍后打印。
我想要的是如果在第一行末尾找到 \
则能够连接 2 行,然后分配分隔的“2 行”(现在是一行)的每个元素通过分隔符“”到我稍后可以调用打印的字段。但我还想删除行尾不需要的字符 \
。
这是我希望将新的组合行存储在数组中的内容
Field-1 Field-2 Field-3 Field-4 Field-5 Field-6;
新数组的第一行将等于
Field-1 = ABC Field-2 = DEF Field-3 = EFG Field-4 = 1.2.3.3 Field-5 = -Ba Field-6 = 10.101.0.10;
如果在第一行末尾找到 \
个字符,将生成新的组合行(2 合一)。
我目前在 Bufferedreader 中的内容 class
public class ReadFile {
private String path;
ReadFile(String filePath) {
path = filePath;
}
public String[] OpenFile() throws IOException {
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
for (int i = 0; i < numberOfLines; i++) {
textData[i] = textReader.readLine();
}
textReader.close();
return textData;
}
//Not sure if It's better to have while loop instead of this to reach end of file, let me know what you think?
int readLines() throws IOException {
FileReader f2r = new FileReader(path);
BufferedReader bf = new BufferedReader(f2r);
String aLine;
int numberOfLines = 0;
while ((aLine = bf.readLine()) != null) {
numberOfLines++;
}
bf.close();
return numberOfLines;
}
}
您正在阅读该文件两次。一个确定它的长度,另一个读取行。请改用可变大小的容器,这样您就可以在不知道文件长度的情况下读取文件。
您可以使用 string.chartAt(string.length-1).
检测一行是否以“\”结尾
下面是将这两个原则付诸实践的代码:
public String[] OpenFile() throws IOException {
List<String> lines = new ArrayList<>(); // Store read lines in a variable
// size container
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
String partialLine = null; // Holds a previous line ending in \ or
// null if no such previous line
for (;;)
{
String line = textReader.readLine(); // read next line
if ( line==null )
{ // If end of file add partial line if any and break out of loop
if ( partialLine!=null )
lines.add(partialLine);
break;
}
boolean lineEndsInSlash = line.length()!=0 &&
line.charAt(line.length()-1)=='\';
String filteredLine; // Line without ending \
if ( lineEndsInSlash )
filteredLine = line.substring(0, line.length()-1);
else
filteredLine = line;
// Add this line to previous partial line if any, removing ending \ if any
if ( partialLine==null )
partialLine = filteredLine;
else
partialLine += filteredLine;
// If the line does not end in \ it is a completed line. Add to
// lines and reset partialLine to null. Otherwise do nothing, next
// iteration will keep adding to partial line
if ( !lineEndsInSlash )
{
lines.add(partialLine);
partialLine = null;
}
}
textReader.close();
return lines.toArray( new String[lines.size()] );
}
我将 String[] 保留为 return 类型,因为这可能是您无法避免的要求。但我建议您尽可能将其更改为 List。是比较合适的类型。
为此,OpenFile 应该像这样更改:
public List<String> OpenFile() throws IOException {
.......
return lines; /// Instead of: return lines.toArray( new String[lines.size()] );
}
它会像这样使用:
public static void main( String[] args )
{
try {
ReadFile file = new ReadFile("/home/user/file.txt");
List<String> aryLines = file.OpenFile();
for ( String s : aryLines) {
System.out.println(s);
}
}
catch ( IOException ex)
{
System.out.println( "Reading failed : " + ex.getMessage() );
}
}
这将读取文本文件并将以“\”结尾的所有行与下一行连接起来。
这里有两个重要说明,这假设输入是正确的并且 \ 字符是该行中的最后一个字符(如果这不是真的,您将不得不清理输入),并且最后一行该文件不以反斜杠结尾。
try (Bufferedreader br = new BufferedReader(new FileReader(file))) {
String line;
StringBuilder concatenatedLine = new StringBuilder();
List<String> formattedStrings = new ArrayList<String>();
while((line = br.readLine()) != null){
//If this one needs to be concatenated with the next,
if( line.charAt(line.length() -1) == '\' ){
//strip the last character from the string
line = line.substring(0, line.length()-1);
//and add it to the StringBuilder
concatenatedLine.append(line);
}
//If it doesn't, this is the end of this concatenated line
else{
concatenatedLine.append(line);
//Add it to the formattedStrings collection.
formattedStrings.add(concatenatedLine.toString());
//Clear the StringBuilder
concatenatedLine.setLength(0);
}
}
//The formattedStrings arrayList contains all of the strings formatted for use.
}
您可以使用 decorator pattern 来定义具有您想要的行为的新 BufferedReader
。在这里,我将 BufferedReader
子类化以覆盖 .readLine()
的行为,以便它将以给定字符结尾的行视为延续。
public class ConcatBufferedReader extends BufferedReader {
private final char continues;
public ConcatBufferedReader(char continues, Reader in) {
super(in);
this.continues = continues;
}
@Override
public String readLine() throws IOException {
StringBuilder lines = new StringBuilder();
String line = super.readLine();
while (line != null) {
if (line.charAt(line.length()-1) == continues) {
lines.append(line.substring(0, line.length()-1)).append(' ');
} else {
return lines.append(line).toString();
}
line = super.readLine();
}
// Handle end-of-file
return lines.length() == 0 ? null : lines.toString();
}
}
然后您可以像使用其他任何东西一样使用它 BufferedReader
,例如:
try (BufferedReader reader = new ConcatBufferedReader('\',
Files.newBufferedReader(yourFile))) {
...
}
使用 BufferedReader:我有一个文本文件,其中包含如下所列的类似行。 文本文件行示例:
ABC DEF EFG 1.2.3.3 MGM -Ba\
10.101.0.10
如何删除 -Ba
之后的行尾字符 \
并将下一个 line/Field 连接到第一行以获得新行,然后将其存储在数组中稍后打印。
我想要的是如果在第一行末尾找到 \
则能够连接 2 行,然后分配分隔的“2 行”(现在是一行)的每个元素通过分隔符“”到我稍后可以调用打印的字段。但我还想删除行尾不需要的字符 \
。
这是我希望将新的组合行存储在数组中的内容
Field-1 Field-2 Field-3 Field-4 Field-5 Field-6;
新数组的第一行将等于
Field-1 = ABC Field-2 = DEF Field-3 = EFG Field-4 = 1.2.3.3 Field-5 = -Ba Field-6 = 10.101.0.10;
如果在第一行末尾找到 \
个字符,将生成新的组合行(2 合一)。
我目前在 Bufferedreader 中的内容 class
public class ReadFile {
private String path;
ReadFile(String filePath) {
path = filePath;
}
public String[] OpenFile() throws IOException {
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
for (int i = 0; i < numberOfLines; i++) {
textData[i] = textReader.readLine();
}
textReader.close();
return textData;
}
//Not sure if It's better to have while loop instead of this to reach end of file, let me know what you think?
int readLines() throws IOException {
FileReader f2r = new FileReader(path);
BufferedReader bf = new BufferedReader(f2r);
String aLine;
int numberOfLines = 0;
while ((aLine = bf.readLine()) != null) {
numberOfLines++;
}
bf.close();
return numberOfLines;
}
}
您正在阅读该文件两次。一个确定它的长度,另一个读取行。请改用可变大小的容器,这样您就可以在不知道文件长度的情况下读取文件。
您可以使用 string.chartAt(string.length-1).
检测一行是否以“\”结尾下面是将这两个原则付诸实践的代码:
public String[] OpenFile() throws IOException {
List<String> lines = new ArrayList<>(); // Store read lines in a variable
// size container
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
String partialLine = null; // Holds a previous line ending in \ or
// null if no such previous line
for (;;)
{
String line = textReader.readLine(); // read next line
if ( line==null )
{ // If end of file add partial line if any and break out of loop
if ( partialLine!=null )
lines.add(partialLine);
break;
}
boolean lineEndsInSlash = line.length()!=0 &&
line.charAt(line.length()-1)=='\';
String filteredLine; // Line without ending \
if ( lineEndsInSlash )
filteredLine = line.substring(0, line.length()-1);
else
filteredLine = line;
// Add this line to previous partial line if any, removing ending \ if any
if ( partialLine==null )
partialLine = filteredLine;
else
partialLine += filteredLine;
// If the line does not end in \ it is a completed line. Add to
// lines and reset partialLine to null. Otherwise do nothing, next
// iteration will keep adding to partial line
if ( !lineEndsInSlash )
{
lines.add(partialLine);
partialLine = null;
}
}
textReader.close();
return lines.toArray( new String[lines.size()] );
}
我将 String[] 保留为 return 类型,因为这可能是您无法避免的要求。但我建议您尽可能将其更改为 List。是比较合适的类型。
为此,OpenFile 应该像这样更改:
public List<String> OpenFile() throws IOException {
.......
return lines; /// Instead of: return lines.toArray( new String[lines.size()] );
}
它会像这样使用:
public static void main( String[] args )
{
try {
ReadFile file = new ReadFile("/home/user/file.txt");
List<String> aryLines = file.OpenFile();
for ( String s : aryLines) {
System.out.println(s);
}
}
catch ( IOException ex)
{
System.out.println( "Reading failed : " + ex.getMessage() );
}
}
这将读取文本文件并将以“\”结尾的所有行与下一行连接起来。
这里有两个重要说明,这假设输入是正确的并且 \ 字符是该行中的最后一个字符(如果这不是真的,您将不得不清理输入),并且最后一行该文件不以反斜杠结尾。
try (Bufferedreader br = new BufferedReader(new FileReader(file))) {
String line;
StringBuilder concatenatedLine = new StringBuilder();
List<String> formattedStrings = new ArrayList<String>();
while((line = br.readLine()) != null){
//If this one needs to be concatenated with the next,
if( line.charAt(line.length() -1) == '\' ){
//strip the last character from the string
line = line.substring(0, line.length()-1);
//and add it to the StringBuilder
concatenatedLine.append(line);
}
//If it doesn't, this is the end of this concatenated line
else{
concatenatedLine.append(line);
//Add it to the formattedStrings collection.
formattedStrings.add(concatenatedLine.toString());
//Clear the StringBuilder
concatenatedLine.setLength(0);
}
}
//The formattedStrings arrayList contains all of the strings formatted for use.
}
您可以使用 decorator pattern 来定义具有您想要的行为的新 BufferedReader
。在这里,我将 BufferedReader
子类化以覆盖 .readLine()
的行为,以便它将以给定字符结尾的行视为延续。
public class ConcatBufferedReader extends BufferedReader {
private final char continues;
public ConcatBufferedReader(char continues, Reader in) {
super(in);
this.continues = continues;
}
@Override
public String readLine() throws IOException {
StringBuilder lines = new StringBuilder();
String line = super.readLine();
while (line != null) {
if (line.charAt(line.length()-1) == continues) {
lines.append(line.substring(0, line.length()-1)).append(' ');
} else {
return lines.append(line).toString();
}
line = super.readLine();
}
// Handle end-of-file
return lines.length() == 0 ? null : lines.toString();
}
}
然后您可以像使用其他任何东西一样使用它 BufferedReader
,例如:
try (BufferedReader reader = new ConcatBufferedReader('\',
Files.newBufferedReader(yourFile))) {
...
}