简体   繁体   English

Java读写同一文件

[英]Java reading and writing to same file

I'm using the following code to search specific files in my computer and write the absolute path in a text file. 我正在使用以下代码在计算机中搜索特定文件,并将绝对路径写入文本文件。 My problem is that every time I run this code it add duplicate lines into text file, i want to add only those lines(file path) which are not written in the text file at that time (no duplicates).. Thank you 我的问题是,每次我运行此代码时,它都会向文本文件中添加重复的行,我只想添加当时未写入文本文件中的行(文件路径)(没有重复)。。谢谢

public static void walkin(File dir) {
    String pattern = ".mp4";
    try {

        PrintWriter out = new PrintWriter(new BufferedWriter(
                new FileWriter("D:\\nawaaaaaa.txt", true)));
        File listFile[] = dir.listFiles();
        if (listFile != null) {
            for (int i = 0; i < listFile.length; i++) {
                if (listFile[i].isDirectory()) {
                    walkin(listFile[i]);
                } else if (listFile[i].getName().endsWith(pattern)
                        && listFile[i].isFile()) {
                    System.out.println(listFile[i].getPath());
                    out.write(listFile[i].toString());
                    out.write("\r\n");
                    // out.close();
                } else {
                    walkin(listFile[i]);
                }
            }
        }
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

} }

If you don't want duplicates in the file, you will need to keep track of the file names you have already written. 如果您不想在文件中重复,则需要跟踪已经写入的文件名。 A HashSet<String> is going for this. HashSet<String>为此。 But I'm surprised the above code works at all given that you keep opening the file at the top of walkin() and walkin() itself is recursive. 但是令我惊讶的是,由于您始终在walkin()的顶部打开文件并且walkin()本身是递归的,因此上述代码完全奏效。 You need to rethink your code a bit. 您需要重新考虑一下代码。 Possibly passing the PrintWriter into walkin() as a parameter. 可能将PrintWriter作为参数传递到walkin()中。

Since you are running the code multiple times ("every time I run this code it add duplicate lines into text file"), so once you finish writing to the file, you read each line and store it in a HashSet<String> . 由于您多次运行该代码(“每次我运行此代码,都会在文本文件中添加重复的行”),因此,一旦完成对该文件的写入,便会读取每一行并将其存储在HashSet<String> And use another writer to write it to the file. 并使用另一个编写器将其写入文件。

BufferedWriter writer = new BufferedWriter(new FileWriter("filename"));
for (String eachUniqueLine: `Your hash set`) {
    writer.write(eachUniqueLine);
    writer.newLine();
}

(It is costly as in you have to do more i/o operation) (这很昂贵,因为您必须执行更多的I / O操作)

Your code works for me, no idea what is the problem on your side, how you are calling it; 您的代码对我有用,不知道您的问题是什么,如何调用它; but you can optimize your code a bit, something as follows (just very quick code, code be made nicer, but to give you an idea): 但是您可以对代码进行一些优化,如下所示(只是非常快速的代码,代码会变得更好,但可以给您一个思路):

public class SomeTest {

    private static HashSet<String> filez = new  HashSet<String> (); 

    public static void walkin(File dir, PrintWriter out) {
        String pattern = ".mp4";
        File listFile[] = dir.listFiles();
        if (listFile != null) {
            for (int i = 0; i < listFile.length; i++) {
                if (listFile[i].getName().endsWith(pattern) && listFile[i].isFile()) {
                    //System.out.println(listFile[i].getPath());
                    if (filez.add(listFile[i].getPath())) {
                        out.write(listFile[i].toString());
                        out.write("\r\n");
                    }
                } else {
                    walkin(listFile[i], out);
                }
            }
        }
    }

    public static void main(String[] args) {
        try {
            File dir = new File("C:\\mydir");
            PrintWriter out = new PrintWriter(new BufferedWriter(
                    new FileWriter("D:\\nawaaaaaa.txt", true)));
            walkin(dir, out);
            out.close();
        } catch (IOException e) {
           //
        }
    }
}

You can use the filez hashset to print stuff, or write your file at the end of the parsing process as well.. your choice. 您可以使用filez哈希集打印内容,也可以在解析过程结束时写入文件。

You need to expand your method into a class that perform this kind of tasks. 您需要将您的方法扩展为执行此类任务的类。

You have two main problem you open a writer for each directory and you call the walkin , for things that do not apply to your logic (and open writer again). 您有两个主要问题:为每个目录打开一个writer,然后调用walkin ,以解决不适用于您的逻辑的问题(然后再次打开writer)。

You should try to design a class that will be able to create an index for you. 您应该尝试设计一个能够为您创建索引的类。

public static void main(String[] args) throws IOException {


    File createTempFile = File.createTempFile("mp4", ".idx");

    FileIndexer fi = new  FileIndexer(createTempFile.getAbsolutePath());

    fi.index("C:\\", "mp4");

    System.out.println(createTempFile);

}


public static class FileIndexer {

    private static final String END_OF_LINE = "\r\n";

    private final String outputPath;
    private final Set<String> index = new HashSet<String>();

    public FileIndexer(String outputPath) {
        this.outputPath = outputPath;
    }

    private boolean isValidPath(String path) {

        return outputPath != null && outputPath.trim().length() > 0; 

    }

    private boolean isValidIndexFile(File file) {

        return file.isFile() && file.canRead() && file.canWrite();

    }

    private void createIndexFile(File file) throws IOException {

        if(file.createNewFile() == false) {
            throw new IOException("Could not create index file");
        }

        this.index.clear();

    }

    private void readIndexFile(File file) throws IOException {

        isValidIndexFile(file);

        index.clear();

        BufferedReader bufferedReader = null;
        try {
             bufferedReader = new BufferedReader(new FileReader(file));

            String line;
            while((line = bufferedReader.readLine()) != null) {
                addToIndex(line);
            }
        } finally {
            if(bufferedReader != null) {
                bufferedReader.close();
            }
        }
    }

    private void addToIndex(String line) {
        index.add(line);
    }

    private PrintWriter openIndex() throws IOException {

        if(isValidPath(outputPath) == false) {
            throw new IOException(String.format("The outputPath is not valid: [%s]",outputPath));
        }

        File indexFile = new File(outputPath);

        if(indexFile.exists()) {
            readIndexFile(indexFile);
        } else {
            createIndexFile(indexFile);
        }

        return new PrintWriter(new BufferedWriter(new FileWriter(this.outputPath, true)));

    }

    public synchronized void index(String pathToIndex, String pattern) throws IOException {

        isValidPath(pathToIndex);

        PrintWriter out = openIndex();

        try {

            File elementToIndex = new File(pathToIndex);
            index(elementToIndex,pathToIndex, out);

        } finally {
            if(out != null) {
                out.close();
            }
        }
    }


    private void index(File elementToIndex, String pattern, PrintWriter out) {


        if(elementToIndex == null) {
            return;
        }


        if(elementToIndex.isDirectory()) {
            for(File file : elementToIndex.listFiles()) {
                index(file,pattern, out);
            }
        }

        if(elementToIndex.isFile() && elementToIndex.getAbsolutePath().endsWith(pattern)) {
            writeToIndex(elementToIndex, out);
        }
    }

    private void writeToIndex(File elementToIndex, PrintWriter out) {

        out.write(elementToIndex.getAbsolutePath());
        out.write(END_OF_LINE);

    }

}

Problem Solved (BTW i'm not sure if it is most efficient solution or not )....... 解决了问题(顺便说一句,我不确定这是否是最有效的解决方案).......

public static void main(String[] args) {

    try {
        File dir = new File("D:\\To Do");
        BufferedWriter out = new BufferedWriter(new FileWriter(
                "D:\\path.txt", true));

        walkin(dir, out);
        out.close();
        readfile();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } // Replace this with a suitable directory
        // walkin(new File("D:/to Do"));
}

public static void walkin(File dir, BufferedWriter out) throws IOException {
    String pattern = ".mp4";

    // BufferedWriter out = new BufferedWriter(
    // new FileWriter("D:\\path.txt",true));
    File listFile[] = dir.listFiles();
    if (listFile != null) {
        for (int i = 0; i < listFile.length; i++) {
            if (listFile[i].getName().endsWith(pattern)
                    && listFile[i].isFile()) {
                if (filez.add(listFile[i].getPath())) {
                    // System.out.println(listFile[i].getPath());
                    out.write(listFile[i].toString());
                    out.write("\r\n");
                    // System.out.println(filez);

                }
            } else {
                walkin(listFile[i], out);
            }
        }
    }
}

public static void readfile() {

    BufferedReader br = null;
    String str;
    try {
        BufferedWriter out = new BufferedWriter(new FileWriter(
                "D:\\duplicate_free.txt"));
        br = new BufferedReader(new FileReader("D:\\path.txt"));
        while ((str = br.readLine()) != null) {
            if (files.contains(str)) {

            } else {
                files.add(str);
            }
        }
        for (String uniq : files) {
            out.write(uniq);
            System.out.println(uniq);
        }
        out.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM