同时创建新文件[重复]

2024-02-26

为了创建一个新的、唯一的文件名,我使用以下代码:

File file = new File(name);
synchronized (sync) {
    int cnt = 0;
    while (file.exists()) {
        file = new File(name + " (" + (cnt++) + ")");
    }
    file.createNewFile();
}

接下来,我使用该文件并将其删除。 当我在多线程情况下执行此操作时,有时会出现异常file.createNewFile():

java.io.IOException: Access is denied
    at java.io.WinNTFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:1012)

以下代码重现了该问题(大多数情况下):

final int runs = 1000;
final int threads = 5;
final String name = "c:\\temp\\files\\file";
final byte[] bytes = getSomeBytes();
final Object sync = new Object();

ExecutorService exec = Executors.newFixedThreadPool(threads);
for (int thread = 0; thread < threads; thread++) {
    final String id = "Runnable " + thread;
    exec.execute(new Runnable() {
        public void run() {
            for (int i = 0; i < runs; i++) {
                try {
                    File file = new File(name);
                    synchronized (sync) {
                        int cnt = 0;
                        while (file.exists()) {
                            file = new File(name + " (" + (cnt++) + ")");
                        }
                        file.createNewFile();
                    }

                    Files.write(file.toPath(), bytes);
                    file.delete();
                } catch (Exception ex) {
                    System.err.println(id + ": exception after " + i
                            + " runs: " + ex.getMessage());
                    ex.printStackTrace();
                    return;
                }
            }
            System.out.println(id + " finished fine");
        }
    });
}
exec.shutdown();
while (!exec.awaitTermination(1, TimeUnit.SECONDS));

方法getSomeBytes()只是生成一定数量的字节,实际内容并不重要:

byte[] getSomeBytes() throws UnsupportedEncodingException,
        IOException {
    byte[] alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ1234567890\r\n"
            .getBytes("UTF-8");
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
        for (int i = 0; i < 100000; i++) {
            baos.write(alphabet);
        }
        baos.flush();
        return baos.toByteArray();
    }
}

当我执行这段代码时,它有时会顺利进行,但大多数时候,它会生成一些异常,例如下面的输出:

Runnable 1: exception after 235 runs: Access is denied
java.io.IOException: Access is denied
    at java.io.WinNTFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:1012)
    at test.CreateFilesTest$1.run(CreateFilesTest.java:36)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Runnable 4: exception after 316 runs: Access is denied
java.io.IOException: Access is denied
    at java.io.WinNTFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:1012)
    at test.CreateFilesTest$1.run(CreateFilesTest.java:36)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Runnable 2: exception after 327 runs: Access is denied
java.io.IOException: Access is denied
    at java.io.WinNTFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:1012)
    at test.CreateFilesTest$1.run(CreateFilesTest.java:36)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Runnable 3 finished fine
Runnable 0 finished fine

有任何想法吗?我已经在 Windows 8 机器上使用 java 1.7.0_45 和 1.8.0_31 进行了测试,结果相同。

不确定问题是否与问题相同这个问题 https://stackoverflow.com/questions/10516472/file-createnewfile-randomly-fails,但它可以是。在我看来,在同一进程中使用多个线程似乎是问题的一部分,但我不能确定这一点,但它的复制速度更快。


好像是在Windows平台上createNewFile如果刚刚删除同名文件,即使在单线程应用程序上,也可能会随机失败。看这个问题 https://stackoverflow.com/q/10516472/4856258了解详情。要解决您的问题,您可以尝试忽略IOException来自createNewFile并继续。像这样的事情:

synchronized (sync) {
    int cnt = 0;
    while (true) {
        try {
            if(file.createNewFile())
                break;
        } catch (IOException e) {
            // continue;
        }
        file = new File(name + " (" + (cnt++) + ")");
    }
}

请注意,您不需要检查file.exists()调用为createNewFile()方便地返回文件是否创建成功。

请注意,如果您控制创建的所有临时文件并且不关心确切的文件名,通常不需要锁定。你可以只使用全局AtomicLong获取下一个文件名或将线程 ID 附加到文件名。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

同时创建新文件[重复] 的相关文章

  • 从 MS Access 中提取 OLE 对象(Word 文档)

    我有一个 Microsoft Access 数据库 其中包含一个包含 Microsoft Word 文档的 OLE 对象字段 我试图找到代码来检索保存在 OLE 对象中的文件 以便用户可以从我的 JavaFx 应用程序中的按钮下载它 但没有
  • 从文本文件中删除特定字符

    我对 Python 和编码都很陌生 我当时正在做一个小项目 但遇到了一个问题 44 1 6 23 2 7 49 2 3 53 2 1 68 1 6 71 2 7 我只需要从每行中删除第三个和第六个字符 或者更具体地说 从整个文件中删除 字符
  • 在 Cordova 中合并文件的多个部分

    在我的 Cordova 应用程序中 我正在下载任意文件 例如图像或视频文件 这是通过 Cordova 文件传输插件和 Range 标头完成的 因为我需要分段下载文件 我的问题是 我想将几 个小 字节 文件合并回原来的文件中 他们曾经在其中使
  • Android 中 localTime 和 localDate 的替代类有哪些? [复制]

    这个问题在这里已经有答案了 我想使用从 android API 获得的长值 该值将日期返回为长值 表示为自纪元以来的毫秒数 我需要使用像 isBefore plusDays isAfter 这样的方法 Cursor managedCurso
  • tomcat 7.0.50 java websocket 实现给出 404 错误

    我正在尝试使用 Java Websocket API 1 0 JSR 356 中指定的带注释端点在 tomcat 7 0 50 上实现 websocket 以下是我如何对其进行编码的简要步骤 1 使用 ServerEndpoint注解编写w
  • FileNotFoundException - Struts2 文件上传

    Strange FileNotFoundException使用Struts2上传文件时 这是 JSP 的一部分
  • 如何在java Spring Boot中实现通用服务类?

    我有许多具有重复代码的服务 我想知道如何实现通用服务 以便我的所有服务都可以扩展它 服务接口示例 重复代码 Service public interface IUserService List
  • 在 MongoDB 和 Apache Solr 之间同步数据的简单方法

    我最近开始使用 MongoDB 和 Apache Solr 我使用 MongoDB 作为数据存储 并且希望 Apache Solr 为我的数据创建索引 以实现应用程序中的搜索功能 经过一些研究 我发现 基本上有两种方法可以在 MongoDB
  • 用于缓存的 Servlet 过滤器

    我正在创建一个用于缓存的 servlet 过滤器 这个想法是将响应主体缓存到memcached 响应正文由以下方式生成 结果是一个字符串 response getWriter print result 我的问题是 由于响应正文将不加修改地放
  • 为什么某些安装程序需要在运行程序之前重新启动计算机?

    我对部署桌面应用程序相当陌生 所以这是我第一次为我的软件构建安装程序 目前 我安装软件后第一次运行它时 它崩溃了 之后 它运行良好 我仍在调试此问题 但我注意到在安装后和运行软件之前立即重新启动似乎可以修复此崩溃 某些安装程序要求您在运行软
  • 在 Clojure 中解压缩 zlib 流

    我有一个二进制文件 其内容由zlib compress在Python上 有没有一种简单的方法可以在Clojure中打开和解压缩它 import zlib import json with open data json zlib wb as
  • 调整屏幕和字体设置的 WPF 应用程序(或者,我如何将 DLU 与 WPF 中的单元相关联?)

    在MFC中 对话框的设计使用DLUs http msdn microsoft com en us library bb847924 aspx 在 WPF 中 我们以 1 96 英寸为单位指定 虽然这确实会缩放窗口和视觉元素 但我们如何使 W
  • Play.application() 的替代方案是什么

    我是 Play 框架的新手 我想读取conf文件夹中的一个文件 所以我用了Play application classloader getResources Data json nextElement getFile 但我知道 play P
  • Karaf / Maven - 无法解决:缺少需求 osgi.wiring.package

    我无法在 Karaf 版本 3 0 1 中启动捆绑包 该包是使用 Maven 构建的并导入gson http mvnrepository com artifact com google code gson gson 2 3 1 我按照要求将
  • Java 的 PriorityQueue 与最小堆有何不同?

    他们为什么命名PriorityQueue如果你不能插入优先级 它看起来与堆非常相似 有什么区别吗 如果没有区别那为什么叫它PriorityQueue而不是堆 默认的PriorityQueue是用Min Heap实现的 即栈顶元素是堆中最小的
  • 使用 JFreeChart 为两个系列设置不同的 y 轴

    我正在使用 JFreeChart 使用折线图绘制两个数据系列 XYSeries 复杂的因素是 其中一个数据系列的 y 值通常远高于第二个数据系列的 y 值 假设第一个系列的 y 值约为数百万数量级 而第二个数据系列的 y 值约为数百万数量级
  • 将键码转换为相关的显示字符

    在 C Windows Forms 项目中 我有一个不提供 KeyPressed 事件的控件 它是一个 COM 控件 ESRI 映射 它仅提供 KeyUp 和 KeyDown 事件 包含关键事件参数 http msdn microsoft
  • 将对象从手机共享到 Android Wear

    我创建了一个应用程序 在此应用程序中 您拥有包含 2 个字符串 姓名和年龄 和一个位图 头像 的对象 所有内容都保存到 sqlite 数据库中 现在我希望可以在我的智能手表上访问这些对象 所以我想实现的是你可以去启动 启动应用程序并向左和向
  • 如何使用通配符模拟泛型方法的行为

    我正在使用 EasyMock 3 2 我想基于 Spring Security 为我的部分安全系统编写一个测试 我想嘲笑Authentication http docs spring io autorepo docs spring secu
  • 基于 Spring Boot 的测试中的上下文层次结构

    我的 Spring Boot 应用程序是这样启动的 new SpringApplicationBuilder sources ParentCtxConfig class child ChildFirstCtxConfig class sib

随机推荐

  • 返回对一个结构体部分的引用作为另一个结构体的字段[重复]

    这个问题在这里已经有答案了 如果可能的话 我希望将一个结构移动到另一个结构中 并获取第一个结构的部分作为其他结构的部分的引用 而无需克隆或复制 如何以正确的方式去做 fn main let foo Foo new let bar Bar n
  • 未将对象引用设置为 MVC 文件(图像)上传的对象实例[重复]

    这个问题在这里已经有答案了 我是 MVC 新手 我正在遵循教程并收到此错误 我按照教程中的每个步骤进行操作 但仍然遇到相同的错误 这是我的观点的代码 model 234CrudDemo Models ComplaintTicket div
  • 具有自定义频率和持续时间的蜂鸣声

    我想在 Mac Os X 中播放蜂鸣声并指定持续时间和频率 在 Windows 上 可以通过使用来完成蜂鸣功能 http msdn microsoft com en us library windows desktop ms679277 2
  • 如何重写 Django 管理列表中的 queryset count() 方法

    为了避免耗时且昂贵的精确数据库计数查询 我想覆盖count Django 管理类中的方法如下所示 from django contrib import admin from django db import connection class
  • 前端与后端端点(spring boot 和 vuejs)

    某种程度上基于本指南 https jaxlondon com blog java core languages put spring boot und vue js practical use project tutorial https
  • BLE扫描记录说明

    我正在尝试获取UUID Major Minor IDs从以以下形式收到的 BLE 广告中byte 我已经使用了建议的代码here https stackoverflow com questions 22016224 ble obtain u
  • Ruby:如何使用 Curb 发送 JSON POST 请求?

    如何将 CURB 请求的请求正文设置为我的 json 字符串 我正在尝试使用 Curb 执行 JSON POST 请求 My code require rubygems require curb require json myarray m
  • Node.js mongodb 设置默认安全变量

    我正在尝试在本地运行 Node js 脚本 但它给了我以下错误消息 Please ensure that you set the default safe variable to one of the allowed values of t
  • 从一个 Activity 更新存储在另一个 Activity 中的对象

    我正在第一个活动中创建一个名为 AppEngine 的对象 此 AppEngine 对象存储事件的数组列表 并以其中的 2 个事件开始 从第一个活动中 我单击一个按钮 该按钮将我带到第二个活动 在其中我通过使用将事件对象添加到 arrayL
  • Openwhisk:增加并发请求数

    我有一个分布式 Openwhisk 设置 当我尝试一次向一个用户执行 30 多个请求时 出现以下错误 错误 无法调用操作 素数 并发数太多 正在处理的请求 计数 30 允许 30 知道如何增加这个数字吗 如果您使用 ansible 方法部署
  • 计算机图形学:光线追踪和 3D 渲染编程

    我注意到许多顶尖大学都为计算机专业的学生提供与计算机图形学相关的课程 遗憾的是 这是我的大学没有提供的东西 也是我非常想在未来几年内进入的东西 我从一些大学发现的一些项目都很棒 尽管我最感兴趣的是两件事 Raytracing 我想在未来两年
  • google chrome实现了哪个版本的websockets协议草案

    我正在尝试在 java 中实现 websockets 服务器 但我无法理解 google chrome 实现的 websocket 协议版本 在this http blog chromium org search label websock
  • XSLT 有数组的概念吗?

    我以前从未真正使用过 XSLT 正在寻求一些建议 我从 GSA 箱中以 XML 形式返回了以下项目
  • SQL 搜索和替换

    不可否认 对于 SQL 命令我是个菜鸟 一名黑客在我的 WordPress 网站上的每个帖子和页面的末尾插入了一个脚本标签 我试图在 wp posts 表中进行查找和替换 但当我运行模拟查询 这是我所拥有的 UPDATE wp posts
  • HTTP 动词 - 何时使用 GET/POST/PUT/Delete

    当您从事 RESTFUL 服务时 您经常会听到这些术语GET POST PUT DELETE 我的问题是这么多动词背后的想法是什么 我可以在以下人的帮助下实现一切GET动词或者如果我想在消息正文中发布一些大数据 我可以使用POST动词 我认
  • 从 Rails 生成 PDF

    The Ruby On Rails Wiki 列出了几个库 http wiki rubyonrails org rails pages HowtoGeneratePDFss 促进PDF一代在Rails 我需要打印地址标签 以字母格式 因此每
  • 如何为 VisualVM“<未知应用程序>”命名?

    JDK 1 6 捆绑了一个名为 VisualVM 的便捷工具 可让您检查正在运行的 Java 进程并与之交互 其中一项功能是它会自动检测本地计算机上正在运行的 JVM 大多数被列为 pid xxxx 但有些有名称和图标 例如 VisualV
  • REGEXP_EXTRACT(word,r'(\w\w\'\w\w)') 中 r 的含义是什么

    我在 BigQuery 中都找不到答案参考 https cloud google com bigquery query reference regularexpressionfunctions or re2 wiki https code
  • 如何获取 PyObject 的引用计数?

    如何获取a的引用计数PyObject来自 C 有功能Py INCREF and Py DECREF增加 减少它 但我还没有找到任何返回对象引用计数的函数 我需要它用于调试目的 每个对象的引用计数都存储在PyObject本身 在一个名为的变量
  • 同时创建新文件[重复]

    这个问题在这里已经有答案了 为了创建一个新的 唯一的文件名 我使用以下代码 File file new File name synchronized sync int cnt 0 while file exists file new Fil