【问题标题】:Unable to write to a file till some specific line在某些特定行之前无法写入文件
【发布时间】:2018-07-29 16:40:22
【问题描述】:

我正在尝试将文件从一个文件拆分为 4 个不同的文件。所以我将文件除以某个“x”值,并想将文件写入该值,然后从那里继续到下一个文件,直到文件内容结束。

我正在使用缓冲区阅读器检查文件中的一些 x 值,并检查内容是否等于 x 值并进行拆分。

拆分即将到来,但以另一种方式,比如它正在读取文件并写入到行号为“x”。但我需要所有的行,直到文件中出现“x”值。

我在文件中有一个时间,比如开始时间 hh:mm:ss,我正在用我的 x 值检查 hh:mm:ss 并进行如下拆分

// inputs to the below method
//  filePath = "//somepath";
// splitlen = 30;
// name ="somename"; */

public void split(String FilePath, long splitlen, String name) {
        long leninfile = 0, leng = 0;
        int count = 1, data;
        try {
            File filename = new File(FilePath);
            InputStream infile = new BufferedInputStream(new FileInputStream(filename));
            data = infile.read();
            BufferedReader br = new BufferedReader(new InputStreamReader(infile));

            while (data != -1) {
                filename = new File("/Users//Documents/mysrt/" + count + ".srt");
                OutputStream outfile = new BufferedOutputStream(new FileOutputStream(filename));
                String strLine = br.readLine();
                String[] atoms = strLine.split(" --> ");

                if (atoms.length == 1) {
//                   outfile.write(Integer.parseInt(strLine + "\n"));

                }
                else {

                    String startTS = atoms[0];
                    String endTS = atoms[1];
                    System.out.println(startTS + "\n");
                    System.out.println(endTS + "\n");
                    String startTime = startTS.replace(",", ".");
                    String endTime = endTS.replace(",", ".");
                    System.out.println("startTime" + "\n" + startTime);
                    System.out.println("endTime" + "\n" + endTime);
                    String [] arrOfStr = endTime.split(":");

                    System.out.println("=====arrOfStr=====");
                    int x = Integer.parseInt(arrOfStr[1]);
                    System.out.println(arrOfStr[1]);
                    System.out.println("===x repeat==");
                    System.out.println(x);
                    System.out.println("===splitlen repeat==");
                    System.out.println(splitlen);
                    System.out.println(data);
                    System.out.println(br.readLine());
                    System.out.println(br.read());

                    while (data != -1 && x < splitlen) {
                       outfile.write(br.readLine().getBytes());

                        data = infile.read();
                            x++;
                    }

                    System.out.println("===== out of while x =====");
                    System.out.println(br.readLine());
                    System.out.println(x);

                    leninfile += leng;
                    leng = 0;
                    outfile.close();
                    firstPage = false;
                    firstPage = true;
                    count++;
                    splitlen = splitlen + 30;
                    System.out.println("=====splitlen after=====" +splitlen);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

我正在用一些数字增加时间,以读取文件中的下一行并读取到另一个文件中。

这里的 splitlen 是 30 ,所以它将数据写入新文件中的 30 行。然后它增加 splitlen+30 即 60。但是,它正在读取接下来的 60 行并写入下一个文件。

但是我需要用文件内容中提供的时间检查这个 splitlen,我应该拆分那行。

请建议我哪里做错了。如果您提供 sn-p 将不胜感激。

谢谢。

【问题讨论】:

  • 我不太明白你的问题,但我想指出,每次你做System.out.println(br.readLine()); 时,你都是从文件中读取一行而不处理读取的行。
  • 嗨 @JoakimDanielson 我希望你知道 .srt 字幕文件是怎样的。我的实际需要是读取文件的每一行,然后用行中的 endTime 检查 x 值。因此,如果我的 x 值为 30,我将逐行检查所有行,并将停止读取匹配的位置并写入新文件,直到该行满足我的 x 值但在上面的代码中写入新文件,直到文件中的 30 行不是我要找的
  • 好的,但正如我在之前的评论中所写,您正在阅读的文件中跳过了一些行。

标签: java inputstream filereader outputstream


【解决方案1】:

我想这就是你想要的

public void split(String filePath, long splitLen, String name) {
    File fileSource = new File(filePath);
    int count = 0;
    boolean endOfFile = false;
    String lineSeparator = System.getProperty("line.separator");
    int hour = 0; // an accumulator for hours
    int min = 0; // an accumulator for minutes
    int sec = (int) splitLen; // an accumulator for seconds
    int _hour = 0; // hours from the file
    int _min = 0; // minutes from the file
    int _sec = 0; // seconds from the file
    try (   // try with resources to close files automatically
            FileReader frSource = new FileReader(fileSource);
            BufferedReader buffSource = new BufferedReader(frSource);
            ) {
        String strIn = null;
        while(!endOfFile) {
            File fileOut = new File("f:\\test\\mysrt\\" + count + ".srt");
            try (   // try with resources to close files automatically
                    FileWriter fwOut = new FileWriter(fileOut);
                    ) {
                if (strIn != null) {
                    // write out the last line read to the new file
                    fwOut.write(strIn + lineSeparator);
                }
                for (int i = 0; i < splitLen; i++) {
                    strIn = buffSource.readLine();
                    if (strIn == null) {
                        endOfFile = true; // stop the while loop
                        break; // exit the for loop
                    }
                    if (strIn.indexOf("-->") > 0) {
                        String endTime = strIn.split("-->")[1];
                        _hour = extractHours(endTime); // get the hours from the file
                        _min = extractMinutes(endTime); // get the minutes from the file
                        _sec = extractSeconds(endTime); // get the seconds from the file
                        if (_hour >= hour && _min >= min && _sec >= sec) { // if the file time is greater than our accumulators
                            sec += splitLen; // increment our accumulator seconds
                            if (sec >= 60) { // if accumulator seconds is greater than 59, we need to convert it to minutes and seconds
                                min += sec / 60;
                                sec = sec % 60;
                            }
                            if (min >= 60) { if accumulator minutes is greater than 59, we need to convert it to hours and minutes
                                hour += min / 60;
                                min = min % 60;
                            }
                            break; // break out of the for loop, which cause the file to be completed and a new file started.
                        }
                    }
                    fwOut.write(strIn + lineSeparator); // write out to the new file
                }
                fwOut.flush();
            }
            count++;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private int extractMinutes(String time) {
    // You need to implement this, I don't know the format of your time
    return 0;
}

private int extractSeconds(String time) {
    // You need to implement this, I don't know the format of your time
    return 0;
}

【讨论】:

  • 谢谢,但这不是我要找的。它不应该在每 30 行之后拆分。这也是在 30 行之后拆分文件.. 我需要检查行中的 00:30:44 this 30。我必须将 splitlen 与每一行中的内容进行比较。如果满足,则应拆分到该行
  • 调整for 循环以满足您的需要。您可以将其更改为 while(true) 并在需要拆分时将其改为 break;
  • 直到我也实现了..但是阅读一行来与我的 splitlen 进行比较我无法获得
  • 所以,如果我理解你的话,30 是分钟的度量,而不是行计数器,并且你的输入文件中包含带有时间戳的行。并且您想将输入文件分成几个较小的文件,其中包含来自输​​入文件的长达 30 分钟的行。对吗?
  • 考虑到这一点,我已经更新了代码。您将需要从时间开始解析小时、分钟和秒。
【解决方案2】:

您的代码的问题在于您正在查看的时间戳在 HH:MM:ss 中,但使用 splitlenx 变量时您只能使用分钟。

所以你需要同时记录小时和分钟,也许这可以通过一些 DateTime 类来完成,但这是一个简单的 int 解决方案

//somewhere at the top 
int hour = 0;
int minutes = 30;

//where you today increase splitlen
minutes += 30;
if (minutes == 60) {
   hour++;
   minutes = 0;
}

//parse also hours
int y = Integer.parseInt(arrOfStr[0]);
int x = Integer.parseInt(arrOfStr[1]);

//you need to rewrite this to compare x and y against hour and minutes
while (data != -1 && x < splitlen) {

因此,现在您将不会寻找 30、60、90、... 分钟,而是 00:30、01:00、01:30 等。当然,您还必须准备好处理整分钟都没有进入的情况,除非您当然已经这样做了。

checkTime 当然是这里的一个关键方法,当文件被拆分为类成员时,在最后一小时和一分钟可能是个好主意,但它们当然也可以作为参数从split() 发送。

更新

这里是split 方法的简化版本,以举例说明如何解决这个问题,它并不完整,但应该是解决问题的一个很好的起点。我尝试利用.str 文件的构造方式,并利用上述逻辑来确定何时打开新的输出文件。

public void split(String filepath, long splitlen, String name) {
    int count = 1;
    try {
        File filename = new File(filepath);
        InputStream infile = new BufferedInputStream(new FileInputStream(filename));
        BufferedReader br = new BufferedReader(new InputStreamReader(infile));

        FileWriter outfile = createOutputFile(count);
        boolean isEndOfFile = false;
        while (!isEndOfFile) {

            String line = null;
            int i = 1;
            while ((line = br.readLine()) != null) {
                outfile.write(line);

                if (line.trim().isEmpty()) { //last line of group
                    i = 1;
                    continue;
                }

                if (i == 2) { //Timestamp row
                    String[] split = line.split("-->");
                    if (checkTime(split)) {
                        count++;
                        outfile.flush();
                        outfile.close();
                        outfile = createOutputFile(count);
                    }
                }
                i++;
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

private FileWriter createOutputFile(int index) {
    //Create new outputfile and writer 
    return null; 
}

private boolean checkTime(String[] arr) {
    //use start or end time in arr to check if an even half or full hour has been passed
    return true;
}

【讨论】:

  • 是的,这就是我需要的。但是卡住了如何读取一行并比较和写入新文件。现在我最多只能写 30 行、60 行和 90 行等。但是我需要在线路有 30 分钟、60 分钟和 90 分钟等时写入文件。请建议我如何实现这一目标
  • 但这就是我的答案。
  • 你让我检查比较,但无法写出哪一行有 00:30:23 。它正在写入文件中的 30 行号
  • @user6250770 我在答案中添加了split() 的简化版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 2013-05-11
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
相关资源
最近更新 更多