文件处理:字节数组和维度

huangapple go评论138阅读模式
英文:

Processing of a file: byte arrays and dimentions

问题

// 代码部分不要翻译,只返回翻译好的内容

Hello我有一个文件我通过ByteArrayInputStream进行读取我必须追踪剩余的字节以便与稍后添加的进度条相关联

在将字节数组引用的文件放入流之前我会计算它的字节长度每次我从输入流处理一行时我还会计算它的字节长度并将其与整个长度进行比较正如您从下面的代码中看到的我通过setter将此比率保存在变量`newValue`该值表示告诉我进程处于哪个阶段的百分比

问题是该值从不达到100而是在9796.9停止我调试了整个过程并注意到值`passed`从不完全达到值`tot`,而只是以一种使`newValue`接近100但不达到它的方式靠近它有人能解释一下吗

以下是代码

private String fName = ""; // 这是我保存文件名的地方
private byte[] docData = new byte[] {}; // 这是我存储文件数据的地方

public void printAndProcess() {

    InputStream is = null;
    BufferedReader bfReader = null;
    try {
        is = new ByteArrayInputStream(getDocData());
        bfReader = new BufferedReader(new InputStreamReader(is));
        String temp = null;
        int tot = getDocData().length;
        int passed = 0;
        while ((temp = bfReader.readLine()) != null) {
            passed += temp.getBytes().length;
            setNewValue((double) (passed * 100) / tot);
            System.out.println(temp);

        }
        System.out.println(getNewValue());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (is != null) is.close();
        } catch (Exception ex) {

        }
    }

}
// 这里是已通过Servlet保存的文件(名称 + 数据),为了完整起见,我将它保留在这里:

public class UpServlet extends HttpServlet {

    private static final long serialVersionUID = -4057880812848897784L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("IN GET");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("IN POST");
        try {
            List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
            for (int ix = 0; ix < items.size(); ix++) {
                FileItem item = (FileItem) items.get(ix);
                if (!item.isFormField()) {
                    String fName = item.getName();
                    if (fName.indexOf("\\") > 0) fName = fName.substring(fName.lastIndexOf("\\") + 1, fName.length());
                    InputStream filecontent = item.getInputStream();

                    if (request.getSession().getAttribute("myController") != null) {
                        MyController myController = (MyController) request.getSession().getAttribute("myController");
                        myController.setfName(fName);
                        myController.setDocData(readFully(filecontent));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static byte[] readFully(InputStream stream) throws IOException {
        byte[] buffer = new byte[8192];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        int bytesRead;
        while ((bytesRead = stream.read(buffer)) != -1) {
            baos.write(buffer, 0, bytesRead);
        }
        return baos.toByteArray();
    }

}
英文:

Hello i have a file which i am reading via ByteArrayInputStream. I have to keep track of the byte that are left to read because i need to put that information in relation to a progress bar that will be added later on.

Before putting the byte array referred to the file into the stream i am calculating its lenght in bytes. Every time i process a line from the input stream i am also calculating it's lenght in bytes and comparing it to the whole lenght. As you can see from the code below i am saving this ratio inside the variable newValue via a setter. That value represents a percentage that tells me at which point the process is.

The problem is that that value never reaches 100 but stops at 97(96.9). I debugged the whole thing and noticed that the value passed never reaches exactly the value tot but only approaches it in a way that the newValue approaches to 100 without reaching it. Does anybody have an explanation?

Here the code:

private String fName =&quot;&quot;; // this is where i save the file name
private byte[] docData = new byte[] {}; // this is where i store file data
public void printAndProcess() {
InputStream is = null; 
BufferedReader bfReader = null;
try {
is = new ByteArrayInputStream(getDocData());
bfReader = new BufferedReader(new InputStreamReader(is));
String temp = null;
int tot = getDocData().length;
int passed = 0; 
while((temp = bfReader.readLine()) != null){
passed += temp.getBytes().length;
setNewValue((double) (passed*100)/tot);
System.out.println(temp);
}
System.out.println(getNewValue());
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
if(is != null) is.close();
} catch (Exception ex){
}
}
}

The file (Name + Data) has been saved via a Servlet which i am leaving it for completeness:

public class UpServlet extends HttpServlet
{
private static final long serialVersionUID = -4057880812848897784L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
System.out.println(&quot;IN GET&quot;);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
System.out.println(&quot;IN POST&quot;);
try
{
List&lt;FileItem&gt; items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (int ix = 0; ix &lt; items.size(); ix++)
{
FileItem item = (FileItem) items.get(ix);
if (!item.isFormField())
{
String fName = item.getName();
if (fName.indexOf(&quot;\\&quot;) &gt; 0) fName = fName.substring(fName.lastIndexOf(&quot;\\&quot;) + 1, fName.length()); 
InputStream filecontent = item.getInputStream();
if (request.getSession().getAttribute(&quot;myController&quot;) != null)
{
MyController myController = (MyController) request.getSession().getAttribute(&quot;myController&quot;);
myController.setfName(fName);
myController.setDocData(readFully(filecontent));
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static byte[] readFully(InputStream stream) throws IOException  
{
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = stream.read(buffer)) != -1)
{
baos.write(buffer, 0, bytesRead);
}
return baos.toByteArray();
}
}

答案1

得分: 1

BufferedReaderreadLine()会丢弃行尾字符(\n\r)。

尽量不要将输入流封装在读取器中,因为它们是用于读取文本(字符流)的。

英文:

BufferedReader 's readLine() will discard end of line characters (\n and \r).

Try not to encapsulate your inputstream in readers , which are made for reading text (character streams) .

答案2

得分: 1

temp.getBytes().length可以获得字符串的长度。文件中的每一行末尾都有换行字符(或字符),但是您读取的字符串中不包含这些字符。因此,您不需要将它们添加到passed变量中。

更好的方法是跟踪流的当前位置。查看此问题的答案以获取一些想法:https://stackoverflow.com/questions/240294/given-a-java-inputstream-how-can-i-determine-the-current-offset-in-the-stream

英文:

temp.getBytes().length gives you the length of the string. Every line in the file has the newline character (or characters) at the end, but the string you have read doesn't contain those characters. So you don't add them up to the passed.

A better approach would be to keep track of the current position on the stream. Check out answers to this question for ideas: https://stackoverflow.com/questions/240294/given-a-java-inputstream-how-can-i-determine-the-current-offset-in-the-stream

huangapple
  • 本文由 发表于 2020年7月24日 16:19:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63069669.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定