基于不同的行分隔符

时间:2016-11-05 05:17:48

标签: java

我有一个文本文件。以下是文件的示例。

CN=100
adshnxhndxghdngfhdsfs
dsjfxnudshxf hfgdsh
ldnf jsdbf hdsbf


CN=200
jhnxrhewxrgewhgxew
ejxn jehwbf ewhfbew
jdksfn sbfhb hfe

XN=300
jskhd sa
jd jhgdsxbfgsdhbfgeh
kdsnbdhfhdgfhdbfhd
CN=400
jhnxrhewxrgewhgxew
ejxn jehwbf ewhfbew
jdksfn sbfhb hfe

XN=500
jhnxrhewxrgewhgxew
ejxn jehwbf ewhfbew
jdksfn sbfhb hfe

我想在行分隔符的基础上将此文件拆分为不同的文件。但在我的文件中,只有=作为行分隔符不变。使用etl我尝试使用行分隔符作为=并获得不同的文件,但那些不是预期的输出和性能问题,因为我必须多次读取文件以获取过滤数据,即使该输出不符合确切的要求

我不是一名java开发人员,但我需要一点帮助。我希望我的预期在上面给出的一个文件中的多个文件中,如此

File one

CN=100
adshnxhndxghdngfhdsfs
dsjfxnudshxf hfgdsh
ldnf jsdbf hdsbf


File two

CN=200
jhnxrhewxrgewhgxew
ejxn jehwbf ewhfbew
jdksfn sbfhb hfe


File three

XN=300
jskhd sa
jd jhgdsxbfgsdhbfgeh
kdsnbdhfhdgfhdbfhd


File four

CN=400
jhnxrhewxrgewhgxew
ejxn jehwbf ewhfbew
jdksfn sbfhb hfe


File five

XN=500
jhnxrhewxrgewhgxew
ejxn jehwbf ewhfbew
jdksfn sbfhb hfe

我可以提出任何建议,以便我可以使用java执行此活动吗?因为我认为使用java所有进程都可以在读取文件的同时完成。然后我也可以在etl工具中尝试你的建议。

我尝试过:

在etl中,我正在使用" ="作为行分隔符并在此基础上接收拆分文件。所以我的分离文件就像这样:

------
File one

CN
---------------
file two

100
adshnxhndxghdngfhdsfs
dsjfxnudshxf hfgdsh
ldnf jsdbf hdsbf


CN
------------------------
file three

200
jhnxrhewxrgewhgxew
ejxn jehwbf ewhfbew
jdksfn sbfhb hfe

XN
----------------------
file four

300
jskhd sa
jd jhgdsxbfgsdhbfgeh
kdsnbdhfhdgfhdbfhd
CN
-----------------------
file five

400
jhnxrhewxrgewhgxew
ejxn jehwbf ewhfbew
jdksfn sbfhb hfe

XN
-------------------------------

我收到了这些文件的种类,并在将文件添加回进入不同文件的字符后再次使用etl。所以它就像一次又一次地读取文件,甚至没有得到确切的预期输出影响性能。

这是我从互联网上想出来处理我的文件

private String currentFile = "root.txt";

public static final String REGEX = "^\w+=\d+";

public void foo() throws Exception{

  Path path = Paths.get("path/to/your/input/file.txt");
  Files.lines(path).forEach(line -> {
    if(line.matches(REGEX)) {
      //Extract the digit and update currentFile
      currentFile = "File DOC_ID_"+line.substring(3, line.length())+".txt";
      System.out.println("Current file is now : currentFile);
    } else {
      System.out.println("Writing this line to "+currentFile + " :" + line);
      //Files.write(...);
    }
  });

请分享您的意见,然后我会尝试从那里开始。

先谢谢

3 个答案:

答案 0 :(得分:2)

您的代码似乎没问题。您只需要添加文件编写器。自从作家"需要传递给"闭包中的代码",我让作者成为该类的成员。

import java.io.*;
import java.nio.*;
import java.nio.file.*;
import java.util.stream.*;

class FileTest {
  public String currentFile="";
  public BufferedWriter writer=null;
  public final String REGEX = "^\\s*\\w+=\\d+\\s*$";

  public void test() {
    try {
      Files.lines(Paths.get("root.txt")).forEach(line -> {
        try {
          if (line.matches(REGEX)) {
            currentFile = "File_DOC_ID_"+line.substring(3, line.length())+".txt";
            System.out.println("Current file is now : " + currentFile);
            if (writer!=null) writer.close(); writer=null;
            writer = Files.newBufferedWriter(Paths.get(currentFile));
            if (writer==null) System.out.println("Failed to open file!\n");

          } else {
            System.out.println("Writing this line to "+currentFile + " :" + line);
            writer.write(line);
          }
        }
        catch(Exception e) { System.out.println(e);}
      });
    }
    catch(Exception e) { System.out.println(e);}
  }
}

class FileTester {
  public static void main(String args[]) {
    FileTest ft=new FileTest(); ft.test();
  }
}

答案 1 :(得分:1)

我会把事情搞得一团糟。想想你在阅读文件时经常要做的事情......每次你读一行你可能只需要在当前文件中写一个常规行,或者你已经到达了一个新文件的开头即可...当你到达一行“=”时。从必须启动新文件开始,您必须保存/关闭当前文件,解析字符串以获取新文件的文件名,使用解析行中的名称创建新文件,然后继续阅读文件,直到您到达文件的下一个“=”或结尾。下面是psuedo代码,提供了一种可能的方法,使其更容易。

编辑 - 更改为不为每一行创建文件:(

data = open file to read
read data to get the first “=” to get the first file name
ParseStringToGetFileName
While not data EOF 
   curWriteFile = GetNewFile to write to with supplied file name
   while readline does not equal “=” OR EOF
     read the next line
     write to curWriteFile 
   end while
   SaveClose write file
   If not EOF
      ParseStringToGetFileName
End while not EOF

希望这有帮助

答案 2 :(得分:0)

为了让生活更轻松,您的文件名可以是所谓的行分隔符中提供的内容(即: CN = 100.txt CN = 200.txt 等)。通过查看示例文件内容并按照您的说法,行分隔符行包含一个等于( = )字符,这对于您正在处理的数据文件来说显然很典型。

我在下面提供的示例方法代码假设等于( = )字符将始终作为行中的第三个​​字符驻留分隔线。在提供的目标文件夹路径中保存到磁盘的文件名实际上是包含在同一行分隔符行上的文本。

如果提供的目标文件夹路径不存在,则会自动创建。

对所提供的主数据文件执行所有必需处理的代码在单独的线程中运行,以便在文件处理在后台运行时,其他工作可以在应用程序中继续(控制台输出始终显示正在进行的操作)。

包含完全相同的行分隔符文本的数据将附加到该名称的文件中,除非该文件尚未存在,在这种情况下它会自动创建。

与每个行分隔符相关的数据通过空行与先前的行分隔符行块条目分开,以便于阅读。

以下是 processFileData()方法:

private static void processFileData(String dataFilePath, String destinationFolderPath) {
    // Establish a new Thread for processing file data...
    Thread dataProcessingThread = new Thread(new Runnable() {
        @Override
        public void run() {
            //Keep things running until this thread is Interrupted
            while (!Thread.currentThread().isInterrupted()) {
                BufferedReader br = null;
                try {
                    // Does Data file exist
                    File file = new File(dataFilePath);
                    if (!file.exists()) {
                        System.out.println("ERROR - Main Data File Not Found!\n\n" 
                                         + dataFilePath);
                        return;
                    }   
                    // Does Destination Folder path exist?
                    // If not then create the path.
                    file = new File(destinationFolderPath);
                    if (!file.exists() && !file.isDirectory()) { file.mkdirs(); }   

                    //Read in the Main Data File...
                    String srcFileLine = null;
                    String sep = System.getProperty("line.separator");

                    br = new BufferedReader(new FileReader(dataFilePath));
                    while((srcFileLine = br.readLine()) != null){
                        if (!srcFileLine.trim().equals("")) {
                            // Is an = character detected in the third position
                            // of the read in string?
                            if (srcFileLine.substring(2, 3).equals("=")) {
                                // Yes, this must be the Row Separator line so
                                // let's use it to create our file name.
                                String curFile = srcFileLine.trim() + ".txt";
                                // Apply the file name to the provided destination folder path.
                                String fileName = destinationFolderPath + "/" + curFile;
                                // Display the file name currently being processed.
                                System.out.println("\nProcessing File: --> " + curFile);
                                // Write the Row Separator line to its respective file
                                FileWriter writer = new FileWriter(fileName, true);
                                BufferedWriter bw = new BufferedWriter(writer);
                                bw.write(srcFileLine.trim() + sep);
                                // Continue reading the Main Data File to acquire
                                // the data lines related to the Row Separator
                                while ((srcFileLine = br.readLine()) != null && !srcFileLine.equals("") && 
                                                                  !srcFileLine.substring(2, 3).equals("=")){
                                    // Display the current line being saved to file
                                    System.out.println("Writing this line to " + curFile + " : " + srcFileLine);
                                    // Write the current line to file.
                                    bw.write(srcFileLine.trim() + sep);
                                }
                                // Add a blank line to the file indicating the end of block
                                bw.write("" + sep);
                                // Close the file currently being written to.
                                bw.close(); writer.close();
                            }
                        }   
                    }
                    // Close the Main Data File reader.
                    br.close();
                } 
                catch (FileNotFoundException ex) { System.out.println(ex.getMessage()); } 
                catch (IOException ex) { System.out.println(ex.getMessage()); } 
                // Kill this processing thread
                Thread.currentThread().interrupt();
            }
        }
    });

    // Start the File data Processing but only if it isn't 
    // already doing so.
    if (!dataProcessingThread.isAlive()) { dataProcessingThread.start(); }
}

以下是您可以使用上述方法的方法:

processFileData("C:/CompanyData/MainDataFile.txt", C:/CompanyData/ProcessedData");

那是......